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

Laziness

 Laziness

Slides from my talk about lazy evaluation at the May RUG::B (Ruby Users Group Berlin) meetup.

Centered in Ruby, contains also some Haskell, Clojure, and pictures of cute sleeping animals.

Sergio Gil

May 02, 2013
Tweet

More Decks by Sergio Gil

Other Decks in Programming

Transcript

  1. “evaluation strategy which delays the evaluation of an expression until

    its value is needed” http://en.wikipedia.org/wiki/Lazy_evaluation
  2. (defn fibonacci [] (map first (iterate (fn [[a b]] [b

    (+ a b)]) [0 1]))) (take 20 (fibonacci))
  3. def fibonacci all_pairs.map(&:first) end def all_pairs pairs = [[0, 1]]

    loop do pairs << next_pair(*pairs.last) end pairs end def next_pair(a, b) [b, a + b] end fibonacci.take(20)
  4. def fibonacci all_pairs.map(&:first) end def all_pairs pairs = [[0, 1]]

    loop do pairs << next_pair(*pairs.last) end pairs end def next_pair(a, b) [b, a + b] end fibonacci.take(20)
  5. def fibonacci all_pairs.map(&:first) end def all_pairs pairs = [[0, 1]]

    loop do pairs << next_pair(*pairs.last) end pairs end def next_pair(a, b) [b, a + b] end fibonacci.take(20)
  6. def fibonacci all_pairs.map(&:first) end def all_pairs pairs = [[0, 1]]

    loop do pairs << next_pair(*pairs.last) end pairs end def next_pair(a, b) [b, a + b] end fibonacci.take(20) never
  7. (defn fibonacci [] (map first (iterate (fn [[a b]] [b

    (+ a b)]) [0 1]))) (take 20 (fibonacci))
  8. (defn fibonacci [] (map first (iterate (fn [[a b]] [b

    (+ a b)]) [0 1]))) (take 20 (fibonacci)) ; (0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
  9. class Whatever def initialize(param) @param = param end def data

    expensive_calculation(@param) end private def expensive_calculation(param) ... end end
  10. class Whatever def initialize(param) @param = param end def data

    @data ||= expensive_calculation(@param) end private def expensive_calculation(param) ... end end
  11. unless :: Bool -> a -> Maybe a unless condition

    code = if condition then Nothing else Just code
  12. unless :: Bool -> a -> Maybe a unless condition

    code = if condition then Nothing else Just code > unless (10 > 5) "whatever"
  13. unless :: Bool -> a -> Maybe a unless condition

    code = if condition then Nothing else Just code > unless (10 > 5) "whatever" Nothing
  14. unless :: Bool -> a -> Maybe a unless condition

    code = if condition then Nothing else Just code > unless (10 > 5) "whatever" Nothing > unless (10 > 15) "whatever"
  15. unless :: Bool -> a -> Maybe a unless condition

    code = if condition then Nothing else Just code > unless (10 > 5) "whatever" Nothing > unless (10 > 15) "whatever" Just "whatever"
  16. def my_unless(condition, code) if condition nil else code end end

    def whatever puts "whatever method" :whatever end
  17. def my_unless(condition, code) if condition nil else code end end

    def whatever puts "whatever method" :whatever end > my_unless(10 > 15, whatever)
  18. def my_unless(condition, code) if condition nil else code end end

    def whatever puts "whatever method" :whatever end > my_unless(10 > 15, whatever) whatever method => :whatever
  19. def my_unless(condition, code) if condition nil else code end end

    def whatever puts "whatever method" :whatever end > my_unless(10 > 15, whatever) whatever method => :whatever > my_unless(10 > 5, whatever)
  20. def my_unless(condition, code) if condition nil else code end end

    def whatever puts "whatever method" :whatever end > my_unless(10 > 15, whatever) whatever method => :whatever > my_unless(10 > 5, whatever) whatever method => nil
  21. def my_unless(condition, &code) if condition nil else code.call end end

    def whatever puts "whatever method" :whatever end > my_unless(10 > 15) { whatever } whatever method => :whatever > my_unless(10 > 5) { whatever } => nil
  22. “evaluation strategy which delays the evaluation of an expression until

    its value is needed” http://en.wikipedia.org/wiki/Lazy_evaluation we
  23. class Wadus def calculate # whatever end end wadus1 =

    Wadus.new.lazy wadus2 = Wadus.new.lazy x = wadus1.calculate y = wadus2.calculate # no calculation is actually done puts x # now wadus1.calculate is called # wadus2.calculate never gets called
  24. Fibonacci = Enumerator.new do |e| pair = [0, 1] loop

    do e << pair pair = [pair[1], pair[0] + pair[1]] end end.lazy.map(&:first)
  25. Fibonacci = Enumerator.new do |e| pair = [0, 1] loop

    do e << pair pair = [pair[1], pair[0] + pair[1]] end end.lazy.map(&:first) > Fibonacci.take(10) => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
  26. Fibonacci. select { |n| n % 5 == 0 }.

    take_while { |n| n < 10 ** 6 }
  27. Fibonacci. select { |n| n % 5 == 0 }.

    take_while { |n| n < 10 ** 6 } [0, 5, 55, 610, 6765, 75025, 832040]