Top Banner
Continuations in Ruby Antono Vasiljev Ruby Open Air, 2012
21

Continuations in Ruby (Anton Vasiljev)

May 24, 2015

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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/