continuations in ruby (anton vasiljev)

21
Continuations in Ruby Antono Vasiljev Ruby Open Air, 2012

Upload: -

Post on 24-May-2015

790 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Continuations in Ruby (Anton Vasiljev)

Continuations

in Ruby

Antono VasiljevRuby Open Air, 2012

Page 2: Continuations in Ruby (Anton Vasiljev)

Continuation is basicallyRest of the program

Page 3: Continuations in Ruby (Anton Vasiljev)

Continuations arefirst class objects

in Ruby

Page 4: Continuations in Ruby (Anton Vasiljev)

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

Page 5: Continuations in Ruby (Anton Vasiljev)

Continuations are about

Flow Control

Page 6: Continuations in Ruby (Anton Vasiljev)

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

Page 7: Continuations in Ruby (Anton Vasiljev)

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

Page 8: Continuations in Ruby (Anton Vasiljev)

1| i = 02|3| label :sum4|5| puts i += 16|7| goto :sum, cond: (i < 10)

Page 9: Continuations in Ruby (Anton Vasiljev)

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 10: Continuations in Ruby (Anton Vasiljev)

Continuation are likegoto

with parameters(but jumps only backward)

Page 11: Continuations in Ruby (Anton Vasiljev)

continuations jumps fardef foo

barenddef bar bazenddef baz

$cont[0]end

callcc { |c| $cont = c; foo }

Page 12: Continuations in Ruby (Anton Vasiljev)

Similar to exceptions.But can go down through stack.

Time Machine!

Page 13: Continuations in Ruby (Anton Vasiljev)

Restartable Exceptions

Page 14: Continuations in Ruby (Anton Vasiljev)

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

Page 15: Continuations in Ruby (Anton Vasiljev)

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

Page 16: Continuations in Ruby (Anton Vasiljev)

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

Page 17: Continuations in Ruby (Anton Vasiljev)

require 'continuation'

class Exception class << self attr_accessor :conts end

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

Page 18: Continuations in Ruby (Anton Vasiljev)

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

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

Page 19: Continuations in Ruby (Anton Vasiljev)

You can do with continuation:

Generator objectsFibers/CoroutinesExit from recursion

Other control structures

Page 20: Continuations in Ruby (Anton Vasiljev)

Thanks!

Page 21: Continuations in Ruby (Anton Vasiljev)

http://antono.info/