The excellent article in callcc at
http://www.all-thing.net/Ruby/iterators_generators_and_continuations_in_ruby.html
makes the following statement...
The way to create a continuation is with Kernel#callcc. For what I
imagine are historical reasons, the continuation is passed as an
argument to a block, rather than returned directly. So the idiom to get
a continuation at the current point in the code is this:
c = callcc { |c| c }
Can anyone elaborate on this history?
Or is there a deeper reason than mere history?
Because I find it very confusing.
Thanks
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand
Refactorers do it a little better every time.
John Carter wrote:
The excellent article in callcc at
Bola88 : Agen Judi Bola Qris Bca Nomor 1 di Dunia
makes the following statement...
The way to create a continuation is with Kernel#callcc. For what I
imagine are historical reasons, the continuation is passed as an
argument to a block, rather than returned directly. So the idiom to get
a continuation at the current point in the code is this:
c = callcc { |c| c }
Can anyone elaborate on this history?
Or is there a deeper reason than mere history?
Two reasons, neither particularly historical, come to mind:
1. So you can implement throw/catch-style control structures.
2. So a result can be passed to the continuation.
Both are illustrated by:
p callcc { |c|
c.call "result"
puts "don't get here"
}
puts "got here"
Output:
"result"
got here
Excerpts from John Carter's mail of 6 Mar 2005 (EST):
The excellent article in callcc at
Bola88 : Agen Judi Bola Qris Bca Nomor 1 di Dunia
makes the following statement...
The way to create a continuation is with Kernel#callcc. For what I
imagine are historical reasons, the continuation is passed as an
argument to a block, rather than returned directly. So the idiom to
get a continuation at the current point in the code is this:
c = callcc { |c| c }
Can anyone elaborate on this history?
Or is there a deeper reason than mere history?
The author of that article clearly didn't understand continuations as
well as he thought! The block syntax does indeed serve a purpose: it
becomes useful when you want to pass values around in continuation
calls, as the ol'
if @cont = callcc { |c| c }
## before
end
## before + after
trick doesn't work any more, if nil or false can be passed as values.
See e.g. Bola88 : Agen Judi Bola Qris Bca Nomor 1 di Dunia for a usage case.
I've exchanged a few choice words with the author and he's updated the
article to reflect this.
···
--
William <wmorgan-ruby-talk@masanjin.net>
Joel VanderWerf wrote:
2. So a result can be passed to the continuation.
Duh. Of course you can do that with
c = callcc { |c| c }
as the article says. The first time through, the value assigned to c will be the continuation. The second time (after c.call(x)), the value assigned to c will be arg x.
The block usually wants to return a useful value itself.
···
On Mon, 7 Mar 2005 08:16:17 +0900, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
Joel VanderWerf wrote:
> 2. So a result can be passed to the continuation.
Duh. Of course you can do that with
c = callcc { |c| c }
as the article says. The first time through, the value assigned to c
will be the continuation. The second time (after c.call(x)), the value
assigned to c will be arg x.
--
spooq
Luke Graham wrote:
The block usually wants to return a useful value itself.
Joel VanderWerf wrote:
2. So a result can be passed to the continuation.
Duh. Of course you can do that with
c = callcc { |c| c }
as the article says. The first time through, the value assigned to c
will be the continuation. The second time (after c.call(x)), the value
assigned to c will be arg x.
Just to clarify, this is how c can be assigned a return value other than the continuation:
c = callcc { |c| c }
p c
c.call(3) if c.respond_to?(:call)
Output is:
#<Continuation:0xb7e51f84>
3
···
On Mon, 7 Mar 2005 08:16:17 +0900, Joel VanderWerf > <vjoel@path.berkeley.edu> wrote: