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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    in`block in ':

    unexpected return

    (LocalJumpError)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    hi

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    in `resume':

    dead fiber called

    (FiberError)

    View full-size slide

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

    hi


    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  25. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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


    end
    f.resume('hi')

    hi

    View full-size slide

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

    bye

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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


    View full-size slide

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

    bye

    View full-size slide

  38. 25
    f = Fiber.new do

    Fiber.yield('hi')

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

    View full-size slide

  39. 25
    f = Fiber.new do

    Fiber.yield('hi')

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

    View full-size slide

  40. 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 full-size slide

  41. Five
    (Practical)
    Applications
    27

    View full-size slide

  42. 0.
    Async, non-blocking IO

    and maybe reactive things
    28

    View full-size slide

  43. (Use your imagination here)
    29

    View full-size slide

  44. 1.
    Infinite lists
    30

    View full-size slide

  45. 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 full-size slide

  46. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  52. 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 full-size slide

  53. 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 full-size slide

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

    View full-size slide

  55. 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 full-size slide

  56. 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 full-size slide

  57. 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 full-size slide

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

    View full-size slide

  59. 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 full-size slide

  60. 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 full-size slide

  61. 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 full-size slide

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

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  65. 51
    when Statement
    pieces << instruction.text

    View full-size slide

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

    View full-size slide

  67. 3.
    Resumable exceptions
    53

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  71. 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 full-size slide

  72. 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 full-size slide

  73. 4.
    Run-time dependencies
    59

    View full-size slide

  74. 60
    http://nanoc.ws
    Nanoc

    View full-size slide

  75. 61
    page 1
    page 2
    page 3

    View full-size slide

  76. 61
    page 1
    page 2
    page 3
    page 1

    View full-size slide

  77. 61
    page 1
    page 2
    page 3
    page 1
    page 2

    View full-size slide

  78. 61
    page 1
    page 2
    page 3
    page 1
    page 2

    View full-size slide

  79. 61
    page 1
    page 2
    page 3
    page 1

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  82. 62
    page 1
    page 2
    page 3

    View full-size slide

  83. 62
    page 1
    page 2
    page 3
    page 1

    View full-size slide

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

    View full-size slide

  85. 62
    page 1
    page 2
    page 3
    page 1
    page 2

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  88. 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 full-size slide

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

    View full-size slide