Continuations and ruby

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.


 

Related posts:

  1. A nice example of continuations in ruby

2 Tweets

5 comments

  1. Super cool! I understand the code as well. Now I must think how this can be done in python :))

    [Reply]

  2. maybe i am too dumb but i havent understood it …

    what is .with() doing?

    [Reply]

    ochronus Reply:

    That’s just some of wee’s syntactic sugar for rendering stuff, it’s wee-specific and has nothing special to do with continuations. The whole wee-example is just to show the elegancy that can be achieved. You’re not dumb for not understanding wee-specific stuff :)

    [Reply]

Trackbacks/Pingbacks

  1. A nice example of continuations in ruby | blog@iamnolegend.com [ochronus] - [...] A nice example of using continuations in ruby: exception-continue – related to my post “Continuations and ruby“. [...]

Leave a Reply

Additional comments powered by BackType