>>How would you do the same thing with Continuation.new ? >> >> > >Well, in this case, maybe with Continuation.new acting exactly like callcc >does now. I just think it would look a little cleaner than it does now. >"callcc" seems deceptive because you're not actually calling the >continuation, you're evaluating a block and passing it the continuation, >which it may call later. I think this syntax: > >Continuation.new { |normal_cc| > Continuation.new { |abort_cc| f(normal_cc, abort_cc) } > nil >} > >Makes it more clear that the continuation is being created there, but called >later. > >The reason I like the idea of a no-block form of Continuation.new is that it >would make this: > >arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] >callcc{|$cc|} >puts(message = arr.shift) >$cc.call unless message =~ /Max/ > >Freddie >Herbie >Ron >Max > >Much more clear: > >arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] >cc = Continuation.new >puts(message = arr.shift) >cc.call unless message =~ /Max/ > >Freddie >Herbie >Ron >Max > >In my mental image of how Continuation.new would work, if a block is given, >Continuation#call resumes at the end of the block, just like it does now, but >if no block is given, it would resume right at the point where the >constructor returns, and the value is assigned to cc. > >The only thing this doesn't address is the idea of callcc returning the value >given by Continuation#call. This might mean that Continuation.new isn't the >right syntax for the block version. Something like Continuation.run or >Continuation.run_block might be more appropriate for that version. > >Here's one that seems to work for me: > >class Continuation > def self.new > cc = nil > callcc {|cc| return cc} > cc > end > > def self.run > callcc {|cc| yield(c) } > end >end > > This works, but only because you're implementing both with callcc. If continuations were implemented so that the only way to create one were Continuation.new, then there would effectively be no way to implement Continuation.run, because doing: cc = Continuation.new ... cc.call(a, b, c) would have no way of getting a, b, and c back to where Continuation.new was called (because it doesn't make sense for Continuation.new to return anything but a Continuation object). The only way to implement callcc using Continuation.new (or something like it) would be to have a method that captures the enclosing function's continuation, so that calling the continuation would return from the function in which Continuation.new was called. This essentially comes down to having two methods written in C instead of 1. I guess the bottom line is, you still need callcc (or something like it), even if you have Continuation.new. You can write Continuation.new using callcc, but you can't write callcc using Continuation.new (without having some magic stuff happen). callcc is more general. However, you can, of course, write a little extention that adds the Continuation.new and Continuation.run methods for your own use, if you find those more clear than callcc, which is a nice feature of Ruby.