22
Continuations in Ruby Antono Vasiljev Kiev.rb, 2014

Anton Vasiljev: Continuations in Ruby

Embed Size (px)

Citation preview

Page 1: Anton Vasiljev: Continuations in Ruby

Continuations

in Ruby

Antono VasiljevKiev.rb, 2014

Page 2: Anton Vasiljev: Continuations in Ruby
Page 3: Anton Vasiljev: Continuations in Ruby

Continuation isbasically

Rest of the program

Page 4: Anton Vasiljev: Continuations in Ruby

Continuations arefirst class objects

in Ruby

Page 5: Anton Vasiljev: Continuations in Ruby

irb(main)> c = callcc { |cont| cont } => #<Continuation:0x7f70ad16d030>

Page 6: Anton Vasiljev: Continuations in Ruby

Continuations are about

Flow Control

Page 7: Anton Vasiljev: Continuations in Ruby

1: i = 02: callcc do |cont|3: i = 14: cont.call 5: i = 2 # skipped6: end7:8: i # => 1

Page 8: Anton Vasiljev: Continuations in Ruby

1: i = 02: i = callcc do |cont|3: i = 14: cont.call(2)5: i = 3 # skipped6: end7:8: i # => 2 => Lines: 2, 4

Page 9: Anton Vasiljev: Continuations in Ruby

1| i = 02|3| label :sum4|5| puts i += 16|

7| goto :sum, cond: (i < 10)

Page 10: Anton Vasiljev: Continuations in Ruby

1| LABELS = {}2|3| def label(name)4| callcc { |cont| LABELS[name] = cont }5| end6| 7| def goto(label, args: {})8| LABELS[label].call if args[:cond]9| end

Page 11: Anton Vasiljev: Continuations in Ruby

Continuation are likegoto

with parameters(but jumps only backward)

Page 12: Anton Vasiljev: Continuations in Ruby

continuations jumps far

def foobar

enddef bar bazenddef baz

$cont[0]endcallcc { |c| $cont = c; foo }

Page 13: Anton Vasiljev: Continuations in Ruby

Similar to exceptions.But can go down through stack.

Time Machine!

Page 14: Anton Vasiljev: Continuations in Ruby

Restartable Exceptions

Page 15: Anton Vasiljev: Continuations in Ruby

1| begin2| hello3| rescue Exception => e4| e.restart5| ensure6| e.cleanup7| end

Page 16: Anton Vasiljev: Continuations in Ruby

1| def hello3| i = 04| restartable do5| puts i += 16| raise Exception unless i == 57| end8| end

Page 17: Anton Vasiljev: Continuations in Ruby

1| def restartable2| cont = callcc { |c| c }3| begin4| yield5| rescue Exception => e6| e.continuation = cont7| raise e8| end9| end

Page 18: Anton Vasiljev: Continuations in Ruby

require 'continuation'

class Exception class << self attr_accessor :conts end

def continuation=(cont) self.class.conts ||= {} self.class.conts[self.class] ||= cont end

Page 19: Anton Vasiljev: Continuations in Ruby

def restart self.class.conts[self.class].call end

def cleanup self.class.conts.delete(self.class) endend

Page 20: Anton Vasiljev: Continuations in Ruby

You can do withcontinuation:

Generator objectsFibers/Coroutines

Exit from recursionOther control structures

Page 21: Anton Vasiljev: Continuations in Ruby
Page 22: Anton Vasiljev: Continuations in Ruby

http://antono.info/