Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > What is reason for callcc{|c|c}?

Reply
Thread Tools

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

 
 
John Carter
Guest
Posts: n/a
 
      03-06-2005
The excellent article in callcc at
http://www.all-thing.net/Ruby/iterat...s_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 : http://www.velocityreviews.com/forums/(E-Mail Removed)
New Zealand

Refactorers do it a little better every time.


 
Reply With Quote
 
 
 
 
Joel VanderWerf
Guest
Posts: n/a
 
      03-06-2005
John Carter wrote:
> The excellent article in callcc at
> http://www.all-thing.net/Ruby/iterat...s_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


 
Reply With Quote
 
 
 
 
Joel VanderWerf
Guest
Posts: n/a
 
      03-06-2005
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.


 
Reply With Quote
 
gabriele renzi
Guest
Posts: n/a
 
      03-06-2005
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.
 
Reply With Quote
 
Csaba Henk
Guest
Posts: n/a
 
      03-07-2005
On 2005-03-06, John Carter <(E-Mail Removed)> wrote:
> 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

 
Reply With Quote
 
Luke Graham
Guest
Posts: n/a
 
      03-07-2005
The block usually wants to return a useful value itself.


On Mon, 7 Mar 2005 08:16:17 +0900, Joel VanderWerf
<(E-Mail Removed)> 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


 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      03-07-2005
Luke Graham wrote:
> The block usually wants to return a useful value itself.
>
>
> On Mon, 7 Mar 2005 08:16:17 +0900, Joel VanderWerf
> <(E-Mail Removed)> 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.



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


 
Reply With Quote
 
William Morgan
Guest
Posts: n/a
 
      03-09-2005
Excerpts from John Carter's mail of 6 Mar 2005 (EST):
> The excellent article in callcc at
> http://www.all-thing.net/Ruby/iterat...s_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.

--
William <(E-Mail Removed)>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
802.1x EAP type setting changes for no reason J. Marc Roth Wireless Networking 0 03-22-2005 01:21 AM
Wireless network lost file sharing for no reason =?Utf-8?B?VG9n?= Wireless Networking 1 12-31-2004 01:17 PM
Any reason not to delete IE and OE from hd? tenplay Firefox 5 06-28-2004 02:43 AM
reason for migration from Mozilla 1.6 to Thunderbird? Wolfgang Kern Firefox 1 05-24-2004 12:05 PM
Re: Compilation error reason??? Weng Tianxiang VHDL 1 07-24-2003 03:08 PM



Advertisments