Today I take a look at the concept of continuation, its implementation in ruby and some examples.
As its name suggests, a continuation is an abstract representation of the control state, of the things to come. Practically continuation support in a language means you can “save” your state at a point and return to it later. This is called a first-class continuation.
In ruby, the callcc method is used (it’s Kernel#callcc) to create a Continuation class. Look at this small sample:
def loop
cont=nil
for i in 1..4
puts i
callcc {|continuation| cont=continuation} if i==2
end
return cont
end
c = loop
c.call |
In irb this will print 1,2,3,4 then 3,4 again, then exit. As a script file run by the main ruby interpreter, this will loop forerver as it captures the control state of the program when and where it was called and this includes returning the continuation and then calling it again.
At first sight, continuations/calcc is just a wild beast, a low-level control method, like a goto on steroids, but there’s much more to that than this. Continuation can help re-introcude the concept of state to application flows where they somehow are hard to implement otherwise – like the typical web app flow. For example the wee framework does just that. Look at how smooth and logical this example is (taken from the wee site):
require 'wee'
class Page < Wee::Component
def initialize
add_decoration Wee::PageDecoration.new('Title')
super
end
def render(r)
r.anchor.callback {
if callcc YesNoMessageBox.new('Really delete?')
callcc InfoMessageBox.new('Deleted!')
else
callcc InfoMessageBox.new('Deleted action aborted')
end
}.with("delete?")
end
end
class InfoMessageBox < Wee::Component
def initialize(msg)
@msg = msg
super()
end
def render(r)
r.h1(@msg)
r.anchor.callback { answer }.with('OK')
end
end
class YesNoMessageBox < InfoMessageBox
def render(r)
r.h1(@msg)
r.anchor.callback { answer true }.with('YES')
r.space(1)
r.anchor.callback { answer false }.with('NO')
end
end
Wee.runcc(Page) |
Nice, isn’t it? No magic with sessions, encoding and the application just feels like a real application from the good old desktop-app times.
Today I take a look at the concept of continuation, its implementation in ruby and some examples.
As its name suggests, a continuation is an abstract representation of the control state, of the things to come. Practically continuation support in a language means you can "save" your state at a point and return to it later. This is called a first-class continuation.
In ruby, the callcc method is used (it's Kernel#callcc) to create a Continuation class. Look at this small sample:
def loop
cont=nil
for i in 1..4
puts i
callcc {|continuation| cont=continuation} if i==2
end
return cont
end
c = loop
c.call
In irb this will print 1,2,3,4 then 3,4 again, then exit. As a script file run by the main ruby interpreter, this will loop forerver as it captures the control state of the program when and where it was called and this includes returning the continuation and then calling it again.
At first sight, continuations/calcc is just a wild beast, a low-level control method, like a goto on steroids, but there's much more to that than this. Continuation can help re-introcude the concept of state to application flows where they somehow are hard to implement otherwise - like the typical web app flow. For example the wee framework does just that. Look at how smooth and logical this example is (taken from the wee site):
require 'wee'
class Page < Wee::Component
def initialize
add_decoration Wee::PageDecoration.new('Title')
super
end
def render(r)
r.anchor.callback {
if callcc YesNoMessageBox.new('Really delete?')
callcc InfoMessageBox.new('Deleted!')
else
callcc InfoMessageBox.new('Deleted action aborted')
end
}.with("delete?")
end
end
class InfoMessageBox < Wee::Component
def initialize(msg)
@msg = msg
super()
end
def render(r)
r.h1(@msg)
r.anchor.callback { answer }.with('OK')
end
end
class YesNoMessageBox < InfoMessageBox
def render(r)
r.h1(@msg)
r.anchor.callback { answer true }.with('YES')
r.space(1)
r.anchor.callback { answer false }.with('NO')
end
end
Wee.runcc(Page)
Nice, isn't it? No magic with sessions, encoding and the application just feels like a real application from the good old desktop-app times.
Tagged as:
continuation,
control state,
ruby,
theory
Pingback: A nice example of continuations in ruby | blog@iamnolegend.com [ochronus]