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

Fibers

 Fibers

Denis Defreyne

March 02, 2017
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

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

    View Slide

  2. Basics
    2

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. 7
    f = Fiber.new do
    puts "hi"
    return
    puts "bye"
    end
    f.resume
    hi
    sample.rb:3:

    in`block in ':

    unexpected return

    (LocalJumpError)

    View Slide

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

    View Slide

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

    View Slide

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

    hi

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 11
    f = Fiber.new do
    puts "hi"
    end
    f.resume
    f.resume
    hi
    a.rb:6:

    in `resume':

    dead fiber called

    (FiberError)

    View Slide

  21. 12
    f = lambda do
    puts "hi"
    return
    puts "bye"
    end
    f.call

    hi


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  27. 16
    f = Fiber.new do
    puts 'hi'
    end
    f.resume
    hi

    View Slide

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

    View Slide

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

    View Slide

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


    end
    f.resume('hi')

    hi

    View Slide

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

    bye

    View Slide

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

    View Slide

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

    View Slide

  34. 21
    f = Fiber.new do
    puts 'hi'
    end
    f.resume
    hi

    View Slide

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

    View Slide

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

    View Slide

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


    View Slide

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

    bye

    View Slide

  39. 25
    f = Fiber.new do

    Fiber.yield('hi')

    'bye'
    end
    puts f.resume
    puts f.resume

    View Slide

  40. 25
    f = Fiber.new do

    Fiber.yield('hi')

    'bye'
    end
    puts f.resume
    puts f.resume
    hi
    bye

    View Slide

  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(…)

    View Slide

  42. Five
    (Practical)
    Applications
    27

    View Slide

  43. 0.
    Async, non-blocking IO

    and maybe reactive things
    28

    View Slide

  44. (Use your imagination here)
    29

    View Slide

  45. 1.
    Infinite lists
    30

    View Slide

  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

    View Slide

  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

    View Slide

  48. 33
    class Ints
    def initialize
    @f = Fiber.new { … }
    end
    def each
    loop do
    yield(@f.resume)
    end
    end
    end

    View Slide

  49. 34
    Ints.new.each do |i|
    puts i
    end

    View Slide

  50. 34
    Ints.new.each do |i|
    puts i
    end
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    View Slide

  51. 35
    Ints =
    Enumerator.new do |y|
    v = 0
    loop do
    y << v
    v += 1
    end
    end

    View Slide

  52. (You don’t need fibers for this.)
    36

    View Slide

  53. 2.
    Wizards
    37

    View Slide

  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!

    View Slide

  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

    View Slide

  56. 40
    def ask(s)
    puts s
    print '> '
    gets.chomp
    end
    def say(s)
    puts s
    end
    def stop
    end

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  64. We’ve separated what to do (wizard)

    from how to do it (CLI, GUI, …)
    48

    View Slide

  65. 49
    pieces = []
    answer = nil
    loop do
    instruction = wizard.resume(answer)
    case instruction
    when Question
    when Statement
    when Stop
    end
    end

    View Slide

  66. 50
    when Question
    pieces << instruction.text
    pieces << ''
    pieces << ''
    pieces << ''
    pieces << ''
    return pieces.join(' ')

    View Slide

  67. 51
    when Statement
    pieces << instruction.text

    View Slide

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

    View Slide

  69. 3.
    Resumable exceptions
    53

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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)

    View Slide

  75. 4.
    Run-time dependencies
    59

    View Slide

  76. 60
    http://nanoc.ws
    Nanoc

    View Slide

  77. 61
    page 1
    page 2
    page 3

    View Slide

  78. 61
    page 1
    page 2
    page 3
    page 1

    View Slide

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

    View Slide

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

    View Slide

  81. 61
    page 1
    page 2
    page 3
    page 1

    View Slide

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

    View Slide

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

    View Slide

  84. 62
    page 1
    page 2
    page 3

    View Slide

  85. 62
    page 1
    page 2
    page 3
    page 1

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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(…)

    View Slide

  91. 64
    Q&A
    Find me at @ddfreyne on Twitter, or [email protected]

    View Slide