Fibers

 Fibers

Be732ee41fd3038aa98a0a7e7b7be081?s=128

Denis Defreyne

March 02, 2017
Tweet

Transcript

  1. Fibers DENIS DEFREYNE / RUG::B / MARCH 2ND, 2017

  2. Basics 2

  3. 3 f = lambda do puts "hi" end f.call

  4. 3 f = lambda do puts "hi" end f.call hi

  5. 4 f = Fiber.new do puts "hi" end f.resume

  6. 4 f = Fiber.new do puts "hi" end f.resume hi

  7. 5 f = lambda do puts "hi" end f.call hi

  8. 6 f = lambda do puts "hi" return puts "bye"

    end f.call
  9. 6 f = lambda do puts "hi" return puts "bye"

    end f.call hi
  10. 7 f = Fiber.new do puts "hi" return puts "bye"

    end f.resume
  11. 7 f = Fiber.new do puts "hi" return puts "bye"

    end f.resume hi
  12. 7 f = Fiber.new do puts "hi" return puts "bye"

    end f.resume hi sample.rb:3:
 in`block in <main>':
 unexpected return
 (LocalJumpError)
  13. 8 f = Fiber.new do puts "hi" Fiber.yield puts "bye"

    end f.resume
  14. 8 f = Fiber.new do puts "hi" Fiber.yield puts "bye"

    end f.resume hi
  15. 9 f = lambda do puts "hi" end f.call
 hi

  16. 10 f = lambda do puts "hi" end f.call f.call

  17. 10 f = lambda do puts "hi" end f.call f.call

    hi hi
  18. 11 f = Fiber.new do puts "hi" end f.resume f.resume

  19. 11 f = Fiber.new do puts "hi" end f.resume f.resume

    hi
  20. 11 f = Fiber.new do puts "hi" end f.resume f.resume

    hi a.rb:6:
 in `resume':
 dead fiber called
 (FiberError)
  21. 12 f = lambda do puts "hi" return puts "bye"

    end f.call
 hi

  22. 13 f = lambda do puts "hi" return puts "bye"

    end f.call f.call
  23. 13 f = lambda do puts "hi" return puts "bye"

    end f.call f.call hi hi
  24. 14 f = Fiber.new do puts "hi" Fiber.yield puts "bye"

    end f.resume f.resume
  25. 14 f = Fiber.new do puts "hi" Fiber.yield puts "bye"

    end f.resume f.resume hi bye
  26. 15 Create a fiber Fiber.new { … } Start running

    a fiber f.resume Resume an running fiber f.resume Return from a fiber Fiber.yield
  27. 16 f = Fiber.new do puts 'hi' end f.resume hi

  28. 17 f = Fiber.new do |a| puts a end f.resume('hi')

  29. 17 f = Fiber.new do |a| puts a end f.resume('hi')

    hi
  30. 18 f = Fiber.new do |a| puts a
 
 end

    f.resume('hi')
 hi
  31. 19 f = Fiber.new do |a| puts a Fiber.yield puts

    'bye' end f.resume('hi') f.resume hi
 bye
  32. 20 f = Fiber.new do |a| puts a b =

    Fiber.yield puts b end f.resume('hi') f.resume('bye')
  33. 20 f = Fiber.new do |a| puts a b =

    Fiber.yield puts b end f.resume('hi') f.resume('bye') hi bye
  34. 21 f = Fiber.new do puts 'hi' end f.resume hi

  35. 22 f = Fiber.new do 'hi' end puts f.resume

  36. 22 f = Fiber.new do 'hi' end puts f.resume hi

  37. 23 f = Fiber.new do puts 'hi' end f.resume hi


  38. 24 f = Fiber.new do puts 'hi' Fiber.yield 'bye' end

    f.resume puts f.resume hi
 bye
  39. 25 f = Fiber.new do
 Fiber.yield('hi')
 'bye' end puts f.resume

    puts f.resume
  40. 25 f = Fiber.new do
 Fiber.yield('hi')
 'bye' end puts f.resume

    puts f.resume hi bye
  41. 26 Create a fiber Fiber.new { … } Start running

    a fiber f.resume(…) Resume an running fiber f.resume(…) Return from a fiber Fiber.yield(…)
  42. Five (Practical) Applications 27

  43. 0. Async, non-blocking IO
 and maybe reactive things 28

  44. (Use your imagination here) 29

  45. 1. Infinite lists 30

  46. 31 
 f = Fiber.new do Fiber.yield(0) Fiber.yield(1) Fiber.yield(2) …

    end puts f.resume puts f.resume puts f.resume 0 1 2
  47. 32 f = Fiber.new do v = 0 loop do

    Fiber.yield(v) v += 1 end end puts f.resume puts f.resume puts f.resume 0 1 2
  48. 33 class Ints def initialize @f = Fiber.new { …

    } end def each loop do yield(@f.resume) end end end
  49. 34 Ints.new.each do |i| puts i end

  50. 34 Ints.new.each do |i| puts i end 0 1 2

    3 4 5 6 7 8 9 10 11 12 13
  51. 35 Ints = Enumerator.new do |y| v = 0 loop

    do y << v v += 1 end end
  52. (You don’t need fibers for this.) 36

  53. 2. Wizards 37

  54. 38 What is your first name? > Denis Hi, Denis.

    What is your last name? > Defreyne Got it — Defreyne! Thanks for your help, Denis Defreyne! Bye-bye for now!
  55. 39 first_name = ask "What is your first name?" say

    "Hi, #{first_name}." last_name = ask "What is your last name?" say "Got it -- #{last_name}!" say "Thanks for your help, #{first_name}!" say "Bye-bye for now!" stop
  56. 40 def ask(s) puts s print '> ' gets.chomp end

    def say(s) puts s end def stop end
  57. 41 first_name = ask "What is your first name?" say

    "Hi, #{first_name}." last_name = ask "What is your last name?" say "Got it -- #{last_name}!" say "Thanks for your help, #{first_name}!" say "Bye-bye for now!" stop
  58. 42 wizard = Fiber.new do first_name = ask "What is

    your first name?" say "Hi, #{first_name}." last_name = ask "What is your last name?" say "Got it -- #{last_name}!" say "Thanks for your help, #{first_name}!" say "Bye-bye for now!" stop end
  59. 43 def ask(s) Fiber.yield(Question.new(s)) end def say(s) Fiber.yield(Statement.new(s)) end def

    stop Fiber.yield(Stop.new) end
  60. 44 answer = nil loop do instruction = wizard.resume(answer) case

    instruction when Question when Statement when Stop end end
  61. 45 answer = nil loop do instruction = wizard.resume(answer) case

    instruction when Question puts instruction.text print '> ' answer = gets.chomp when Statement when Stop end end
  62. 46 answer = nil loop do instruction = wizard.resume(answer) case

    instruction when Question puts instruction.text print '> ' answer = gets.chomp when Statement puts instruction.text when Stop end end
  63. 47 answer = nil loop do instruction = wizard.resume(answer) case

    instruction when Question puts instruction.text print '> ' answer = gets.chomp when Statement puts instruction.text when Stop break end end
  64. We’ve separated what to do (wizard) from how to do

    it (CLI, GUI, …) 48
  65. 49 pieces = [] answer = nil loop do instruction

    = wizard.resume(answer) case instruction when Question when Statement when Stop end end
  66. 50 when Question pieces << instruction.text pieces << '<form method="post"

    action="/">' pieces << '<input type="text" name="answer">' pieces << '<input type="submit">' pieces << '</form>' return pieces.join(' ')
  67. 51 when Statement pieces << instruction.text

  68. 52 when Stop return pieces.join(' ')

  69. 3. Resumable exceptions 53

  70. 54 handle_exception do puts 'before' puts Boom.new.throw puts 'after' end.…

  71. 55 handle_exception do puts 'before' puts Boom.new.throw puts 'after' end.on(Boom)

    do |e| e.resume('exceptional') end.…
  72. 56 handle_exception do puts 'before' puts Boom.new.throw puts 'after' end.on(Boom)

    do |e| e.resume('exceptional') end.run
  73. 57 handle_exception do puts 'before' puts Boom.new.throw puts 'after' end.on(Boom)

    do |e| e.resume('exceptional') end.run before exceptional after
  74. 58 handle_exception do puts 'before' puts Boom.new.throw puts 'after' end.run

    before sample.rb:31:
 in `block in run': ohnoes kaboom
 (Boom)
  75. 4. Run-time dependencies 59

  76. 60 http://nanoc.ws Nanoc

  77. 61 page 1 page 2 page 3

  78. 61 page 1 page 2 page 3 page 1

  79. 61 page 1 page 2 page 3 page 1 page

    2
  80. 61 page 1 page 2 page 3 page 1 page

    2
  81. 61 page 1 page 2 page 3 page 1

  82. 61 page 1 page 2 page 3 page 1 page

    3
  83. 61 page 1 page 2 page 3 page 1 page

    3 page 2
  84. 62 page 1 page 2 page 3

  85. 62 page 1 page 2 page 3 page 1

  86. 62 page 1 page 2 page 3 page 1 page

    2
  87. 62 page 1 page 2 page 3 page 1 page

    2
  88. 62 page 1 page 2 page 3 page 1 page

    2 page 3
  89. 62 page 1 page 2 page 3 page 1 page

    2 page 3 page 2
  90. 63 Create a fiber Fiber.new { … } Start running

    a fiber f.resume(…) Resume an running fiber f.resume(…) Return from a fiber Fiber.yield(…)
  91. 64 Q&A Find me at @ddfreyne on Twitter, or denis@stoneship.org.