Continuations in Ruby Antono Vasiljev Ruby Open Air, 2012
May 24, 2015
Continuations
in Ruby
Antono VasiljevRuby Open Air, 2012
Continuation is basicallyRest of the program
Continuations arefirst class objects
in Ruby
irb(main)> c = callcc { |cont| cont } => #<Continuation:0x7f70ad16d030>
Continuations are about
Flow Control
1: i = 02: callcc do |cont|3: i = 14: cont.call 5: i = 2 # skipped6: end7:8: # i => 1
1: i = 02: i = callcc do |cont|3: i = 14: cont.call(2)5: i = 3 # skipped6: end7:8: # i => 2 # See lines: 2, 4
1| i = 02|3| label :sum4|5| puts i += 16|7| goto :sum, cond: (i < 10)
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
Continuation are likegoto
with parameters(but jumps only backward)
continuations jumps fardef foo
barenddef bar bazenddef baz
$cont[0]end
callcc { |c| $cont = c; foo }
Similar to exceptions.But can go down through stack.
Time Machine!
Restartable Exceptions
1| begin2| hello3| rescue Exception => e4| e.restart5| ensure6| e.cleanup7| end
1| def hello3| i = 04| restartable do5| puts i += 16| raise Exception unless i == 57| end8| end
1| def restartable2| cont = callcc { |c| c }3| begin4| yield5| rescue Exception => e6| e.continuation = cont7| raise e8| end9| end
require 'continuation'
class Exception class << self attr_accessor :conts end
def continuation=(cont) self.class.conts ||= {} self.class.conts[self.class] ||= cont end
def restart self.class.conts[self.class].call end
def cleanup self.class.conts.delete(self.class) endend
You can do with continuation:
Generator objectsFibers/CoroutinesExit from recursion
Other control structures
Thanks!
http://antono.info/