What is reason for callcc{|c|c}?

J

John Carter

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 : (e-mail address removed)
New Zealand

Refactorers do it a little better every time.
 
J

Joel VanderWerf

John said:
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?

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
 
J

Joel VanderWerf

Joel said:
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.
 
G

gabriele renzi

John Carter ha scritto:
Can anyone elaborate on this history?

call-with-current-continuation in scheme works like this, passing the
c.c. to a function, and ruby follows this tradition.
 
C

Csaba Henk

c = callcc { |c| c }

Can anyone elaborate on this history?

Or is there a deeper reason than mere history?

Of course, this blocky form is useful (as it's with blocky forms in ruby
usually).

But I think it should be allowed to have a plain "callcc" which would
be equivalent with today's "callcc { |c| c }".

You can just do

module Kernel
alias call_with_current_continuation callcc

def callcc(*a,&b)
b ||= proc{ |c| c }
call_with_current_continuation(*a,&b)
end
end

Just like with fork, but the other way around:

traditional unix-style fork works like:

if pid = fork
# parent code...
else
# child code...
end

(this is the way we'd like to have with callcc)
and ruby introduced the blocky form

fork { #child code }; #parent goes on...

but the traditional style fork remained valid.

As a sidenote: with cvs ruby you can do the following:

if pid = callcc { |c| fork{c.call} }
# parent
else
# child
end

That is, traditional fork style can be defined in terms of blocky fork,
thanks to callcc. This might come handy if you bump into some fork
wrapper which supports only the blocky form (imagine, eg., some
pty_fork, which doesn't have proper implementation in current ruby).

Csaba


Csaba
 
J

Joel VanderWerf

Luke said:
The block usually wants to return a useful value itself.


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
 
W

William Morgan

Excerpts from John Carter's mail of 6 Mar 2005 (EST):
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?

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. http://www.all-thing.net/Ruby/coroutines.html for a usage case.

I've exchanged a few choice words with the author and he's updated the
article to reflect this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top