Here's my entry for the 'writing BASIC in Ruby' competition:

  $lines = {}
  $running = false
  $tron = false
  def line(n,&blk)
    callcc { |$lines[n]| }
    puts "Line #{n}" if $tron and $running
    yield if $running
  end
  def goto n
    $lines[n].call
  end
  def run
    unless $running
      $running = true
      $lines.sort[0][1].call
    $end
  end

  line(100) { puts "Hello World" }
  line(110) { $i = 0 }
  line(120) { if $i > 10 then goto 160 end }
  line(130) { puts "Current $i: %d" % [$i] }
  line(140) { $i = $i + 1 }
  line(150) { goto 120 }
  line(160) { puts "Done!" }
  line(170) { puts "Stopping now" }
  # $tron = true
  run

One thing worth mentioning about continuations is that as far as I can tell,
Continuation#call NEVER RETURNS. You are not pushing the current execution
state onto a stack like Method#call or Proc#call; you are simply replacing
the current execution context, like a longjmp in C. The current execution
thread is lot. In that case perhaps 'call' is not the ideal name for this
method.

The thing I am not sure of is what values of variables, if any, are bound up
in the continuation. Take the following example:

   i = 0
   here = nil
   callcc {|here|}
   puts i
   i = i + 1
   here.call unless i == 10   # here.call is just "goto here"
   puts "Done!"

This is not recursive - as mentioned before, here.call just rewinds to the
point after the callcc.

Now, clearly the *value* of variable 'i' at callcc time is not included in
the continuation object 'here', because when I do 'here.call', the
subsequent 'puts i' shows 'i' with its new value.

I think what confuses me is the discussion on the Wiki about coming to a
crossroads, taking the left path, finding that you get bitten by a dog, and
then deciding that was a bad idea so you 'rewind back in time' to the
crossroads. But if you did this using a Ruby continuation, surely your leg
would still be bleeding?


  preferred_path = "LEFT"
  bleeding = false

  crossroads = nil
  callcc{ |crossroads| }

  puts "At the crossroads"
  puts bleeding ? "I am bleeding!" : "I am OK"

  puts "I am going to go #{preferred_path}"
  if preferred_path == "LEFT"
    sleep 2
    puts "Bitten by dog!"
    bleeding = true
    preferred_path = "RIGHT"
    crossroads.call
  else
    sleep 2
    puts "Hit by train!"
    exit
  end


Regards,

Brian.