Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Basics 2

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

7 f = Fiber.new do puts "hi" return puts "bye" end f.resume hi sample.rb:3:
 in`block in ':
 unexpected return
 (LocalJumpError)

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

11 f = Fiber.new do puts "hi" end f.resume f.resume hi a.rb:6:
 in `resume':
 dead fiber called
 (FiberError)

Slide 21

Slide 21 text

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


Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

15 Create a fiber Fiber.new { … } Start running a fiber f.resume Resume an running fiber f.resume Return from a fiber Fiber.yield

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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


Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

26 Create a fiber Fiber.new { … } Start running a fiber f.resume(…) Resume an running fiber f.resume(…) Return from a fiber Fiber.yield(…)

Slide 42

Slide 42 text

Five (Practical) Applications 27

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

(Use your imagination here) 29

Slide 45

Slide 45 text

1. Infinite lists 30

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

2. Wizards 37

Slide 54

Slide 54 text

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!

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

We’ve separated what to do (wizard) from how to do it (CLI, GUI, …) 48

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

51 when Statement pieces << instruction.text

Slide 68

Slide 68 text

52 when Stop return pieces.join(' ')

Slide 69

Slide 69 text

3. Resumable exceptions 53

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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)

Slide 75

Slide 75 text

4. Run-time dependencies 59

Slide 76

Slide 76 text

60 http://nanoc.ws Nanoc

Slide 77

Slide 77 text

61 page 1 page 2 page 3

Slide 78

Slide 78 text

61 page 1 page 2 page 3 page 1

Slide 79

Slide 79 text

61 page 1 page 2 page 3 page 1 page 2

Slide 80

Slide 80 text

61 page 1 page 2 page 3 page 1 page 2

Slide 81

Slide 81 text

61 page 1 page 2 page 3 page 1

Slide 82

Slide 82 text

61 page 1 page 2 page 3 page 1 page 3

Slide 83

Slide 83 text

61 page 1 page 2 page 3 page 1 page 3 page 2

Slide 84

Slide 84 text

62 page 1 page 2 page 3

Slide 85

Slide 85 text

62 page 1 page 2 page 3 page 1

Slide 86

Slide 86 text

62 page 1 page 2 page 3 page 1 page 2

Slide 87

Slide 87 text

62 page 1 page 2 page 3 page 1 page 2

Slide 88

Slide 88 text

62 page 1 page 2 page 3 page 1 page 2 page 3

Slide 89

Slide 89 text

62 page 1 page 2 page 3 page 1 page 2 page 3 page 2

Slide 90

Slide 90 text

63 Create a fiber Fiber.new { … } Start running a fiber f.resume(…) Resume an running fiber f.resume(…) Return from a fiber Fiber.yield(…)

Slide 91

Slide 91 text

64 Q&A Find me at @ddfreyne on Twitter, or denis@stoneship.org.