Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lazy Evaluation in Swift

Avatar for nghialv nghialv
April 15, 2015

Lazy Evaluation in Swift

Avatar for nghialv

nghialv

April 15, 2015
Tweet

More Decks by nghialv

Other Decks in Programming

Transcript

  1. A programming language uses an evaluation strategy to determine when

    to evaluate the argument(s) of a function call (for function, also read: operation, method, or relation) and what kind of value to pass to the function. “Wikipedia” Evaluation Strategy:
  2. A programming language uses an evaluation strategy to determine when

    to evaluate the argument(s) of a function call (for function, also read: operation, method, or relation) and what kind of value to pass to the function. “Wikipedia” Evaluation Strategy: call-by-value call-by-reference
  3. Eager Evaluation func dosomething() -> Int { println("dosomething") return 1

    } func foo(x: Int, status: String) { println("foo") } foo(dosomething(), "200") output dosomething foo
  4. Eager Evaluation func dosomething() -> Int { println("dosomething") return 1

    } func foo(x: Int, status: String) { println("foo") } foo(dosomething(), "200") output dosomething foo fooؔ਺ͷ࣮ߦલʹdosomething͕ධՁ͞ΕΔ
  5. Eager Evaluation func expensiveComputation() -> Int { println("expensiveComputation") return 1

    } func foo(x: Int, status: String) { println("foo") let result = status == "200" ? x : 0 println("result: \(result)") } foo(expensiveComputation(), "404") output expensiveComputation foo result: 0
  6. Eager Evaluation func expensiveComputation() -> Int { println("expensiveComputation") return 1

    } func foo(x: Int, status: String) { println("foo") let result = status == "200" ? x : 0 println("result: \(result)") } foo(expensiveComputation(), "404") output expensiveComputation foo result: 0 x ͕࢖ΘΕ͍ͯͳ͍ͷʹධՁ͞Εͨʂ
  7. Eager Evaluation func expensiveComputation() -> Int { println("expensiveComputation") return 1

    } func foo(x: Int, status: String) { println("foo") let result = status == "200" ? x : 0 println("result: \(result)") } foo(expensiveComputation(), "404") output expensiveComputation foo result: 0 x ͕࢖ΘΕ͍ͯͳ͍ͷʹධՁ͞Εͨʂ ϞολΠφΠʂ
  8. Function Currying func dosomething() -> Int { println("dosomething") return 1

    } func foo(a: Int)(b: Int) { println("add") } let cFoo = foo(dosomething()) //cFoo(b: 10) output dosomething
  9. Function Currying func dosomething() -> Int { println("dosomething") return 1

    } func foo(a: Int)(b: Int) { println("add") } let cFoo = foo(dosomething()) //cFoo(b: 10) output dosomething ͜ͷ࣌఺ʹ a ͕ධՁ͞ΕΔ
  10. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 println("result: \(result)") } foo({ expensiveComputation() }, "404") output foo result: 0
  11. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 println("result: \(result)") } foo({ expensiveComputation() }, "404") output foo result: 0 ClosureΛ࢖͏ʂ
  12. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 println("result: \(result)") } foo({ expensiveComputation() }, "404") output foo result: 0 ClosureΛ࢖͏ʂ ؾ࣋ͪѱ͍
  13. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: @autoclosure () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 println("result: \(result)") } foo(expensiveComputation(), "404") output foo result: 0
  14. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: @autoclosure () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 println("result: \(result)") } foo(expensiveComputation(), "404") output foo result: 0 ؾ࣋ͪྑ͘ͳͬͨʂ
  15. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: @autoclosure () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 let t1 = x() let t2 = x() println("result: \(result)") } foo(expensiveComputation(), "404") output foo expensiveComputation expensiveComputation result: 0
  16. Call-by-name func expensiveComputation() -> Int { println("expensiveComputation") return 1 }

    func foo(x: @autoclosure () -> Int, status: String) { println("foo") let result = status == "200" ? x() : 0 let t1 = x() let t2 = x() println("result: \(result)") } foo(expensiveComputation(), "404") output foo expensiveComputation expensiveComputation result: 0 x ͕࠶ධՁ͞ΕΔʂ
  17. Call-by-need class Foo { lazy var tmp: Int = {

    println("tmp init") return 1 }() } println("before init") let foo = Foo() println("after init") foo.tmp foo.tmp output before init after init tmp init
  18. Call-by-need class Foo { lazy var tmp: Int = {

    println("tmp init") return 1 }() } println("before init") let foo = Foo() println("after init") foo.tmp foo.tmp output before init after init tmp init ̎ճݺ͹Ε͍ͯΔ͚ͲɼॳظԽ͸̍ճ͚ͩ ඞཁ࣌ͷΈධՁ͢Δ
  19. Call-by-need lazy property global variable static property struct Foo {

    static var tmp: Int = { println("tmp init") return 1 }() static func log() { println("foo") } } let foo = Foo() Foo.log() println("access tmp") let x = Foo.tmp output foo access tmp tmp init
  20. Memoization func memoize<T: Hashable, U>( body: (T)->U ) -> (T)->U

    { var memo = Dictionary<T, U>() return { x in if let q = memo[x] { return q } let r = body(x) memo[x] = r return r } } Fibonacci link: WWDC2014 Advanced Swift (from page 123) Ωϟογϡ͞ΕͨͷͰ࠶ܭࢉ͕ෆཁ
  21. When • Eager evaluation • evaluated completely before the function

    is applied • Call-by-name • evaluate only when needed • evaluate each time value is accessed • Call-by-need • evaluate only when needed • cache result for repeated access