Talk:Call-with-current-continuation

"function" vs. "procedure"
What is in most programming languages called a function, is called a procedure in Scheme; yet the article uses the word "function". Should this not be changed/fixed? 217.10.109.18 (talk) 13:29, 26 February 2017 (UTC)

Cyclic reference
The "Yin Yang Puzzle" uses a (dead) reference to Yin Wang's blog. In Web Archive, it refereed to a Stack Overflow question, and that question referred Wikipedia.

So this is a cyclic reference. We don't know when this puzzle was invented, and who invented this. --137.147.203.50 (talk) 06:14, 23 May 2015 (UTC)

Rationale
This article does not address the issue of why call/cc was created, and what for... -- Karada 15:37, 5 March 2006 (UTC)


 * The rationale should be found in Continuation. --Kanjy 11:38, 7 March 2006 (UTC)

Inaccuracies and false claims
I have removed several inaccuracies and false claims, plus some awkward writing from this page.

I intend to elaborate on the logical implications of call/cc when I have time.

Matthias.f 15:06, 27 July 2007 (UTC)Matthias.f

Logging call/cc
It took me a while to figure out what was happening in the second example, leaving me with the impression that continuations are both:

a) A really clever idea that has expanded my understanding of what a program is.

b) Perhaps the most powerful program-obfuscation technique since self-modifying code.

In order to better understand them, I wrote the following. The first is a modification of call/cc that logs what is happening, and the second is a heavily annotated variant of the list-iteration example, in which I tried to separate each aspect of its use of continuations. I'm no Scheme programmer, and my experience of Lisp has been limited to a few weeks some years ago, but if they help, feel free to use them.

Raybo0 13:35, 19 September 2007 (UTC)

(call/cc (lambda (x) x)) is a no-op, right?
Mathias.f added the call to the first example: http://en.wikipedia.org/w/index.php?title=Call-with-current-continuation&oldid=147459612

And I took it out just now because I'm pretty sure it's redundant and not helpful in explaining the concept.

I'm a Lisp/Scheme n00b, but as I read it, it forms an anonymous function which invokes its only arg, then calls that anonymous function with the current continuation. The function invokes that continuation causing execution to continue where it 'left off'. If I'm wrong, the surrounding text should be edited to explain that line. Crag (talk) 02:35, 9 January 2008 (UTC)


 * Actually, in the line  the lambda expression does not invoke the continuation, it simply returns it. However, I don't see what this line adds to the example, and I agree that this line should have been removed from the example. &mdash; Tobias Bergemann (talk) 07:41, 9 January 2008 (UTC)

as said above, it isn't a no-op. and it is demonstrating that you can get your hands on the continuation, as a first class, displayable object that you can sort of look at, which is something impossible in most languages. also, if you don't know what code does, and can't execute it to find out, you probably shouldn't be editing pages about it. so i put it back. —Preceding unsigned comment added by 67.177.213.111 (talk) 20:34, 21 January 2008 (UTC)


 * I don't see what this line adds to the example as the example doesn't show how the continuation is displayed, and the way continuations are displayed isn't specified in the Scheme standards anyway. Worse, it breaks the flow between the definition of  in the example and its use. Frankly, I find the line more confusing than enlightening and am tempted to remove it again or at least move it. &mdash;Tobias Bergemann (talk) 07:52, 22 January 2008 (UTC)


 * please move it - it's very confusing! I would do it myself, but I don't know what to say about it (and I don't want to just delete it because somebody tried that already and was undone). 149.159.72.139 (talk) 04:07, 30 January 2008 (UTC)

It is true that (call/cc (lambda (x) x)) doesn't have any side effects, but it certainly does return a value, and that value has interesting properties when you call it. That's the point. 64.81.85.44 (talk) 22:41, 6 August 2009 (UTC)
 * It is just an identity function. i.e. a neutral element
 * defines  as  . If you compose any function f with id, it is like multiplying by 1 or adding 0.
 * = = for all.
 * you are confused because you are not seeing pure functional examples. Continuations allow us to program in a pure functional style which has an algebra of programs. That allow us to do things elegantly without confusing side effects. Scheme has imperative features, but that should be avoided whenever it is possible. This article could benefit a lot if more pure functional examples could be chosen. See the proposed change to the first example below to understand how it is evaluated. I only showed how it is evaluated, but I don't like because of the side effects, that are confusing. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 08:29, 25 March 2018 (UTC)

,,  etc.
The semantics of  where changed with the move from R4RS to R5RS. Should the article explain the interaction between  and ,  ,   etc. (see e.g. Revised6 Report on the Algorithmic Language Scheme - Non-Normative Appendices - 11.9 Control features) or would this be too much detail? &mdash;Tobias Bergemann (talk) 09:41, 4 February 2008 (UTC)
 * IMO the article should be language-agnostic, considering that continuations aren't specific to Scheme. Obviously the fact that Scheme's call/cc was the original means that some implementation details might be interesting from a historical point of view, but otherwise I think it's irrelevant. Hairy Dude (talk) 23:50, 8 May 2008 (UTC)
 * Agree in part. Personally I hate that cancer that makes more an more complex a programming language each successive version. R4RS is simple and beautiful. To explain something it is always better to use the most simple example that makes the concept clear, sticking to R4RS to explain the concept is fine from my point of view. However, many readers will be starting with some RnRS, for n>4 version, each with more and more bells and whistles. Being call/cc essentially Scheme, the article should include the variants that you mentioned. However not to explain the main concept, but to explain how it evolved in later Scheme versions. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 08:05, 25 March 2018 (UTC)

Continuations as a generic control mechanism
Anecdotally, it's possible to code any pure Haskell monad using Cont (the continuation monad). Quick googling turned up this set of slides on the topic, though a proper paper would be nice. Hairy Dude (talk) 23:47, 8 May 2008 (UTC)

Generator example
Hi, I'm a little confused about the  example. It doesn't appear that  is ever going to change the value of return because the computation will always be cut short when   is executed. I tested the full code snippet without the  and it seemed to behave exactly the same. I'm new to call/cc so I didn't want to change it incase I was mistaken. thoughts? --Marty.neal (talk) 20:26, 2 March 2009 (UTC)
 * I've restored (set! return ...). When call/cc returns, as it does when the saved continuation is invoked, it's important that the *new* return fails.  If your return continuations are virtually identical, you'll never see the problem, but if they are different, then there's a problem.  Removing the set! has return never change, and so each invocation of the cursor only returns to the continuation of the *first* call.  64.81.85.44 (talk) 22:08, 6 August 2009 (UTC)
 * The explanation why (set! return ..) is important is not convincing, especially in this case where digits are generated regardless of whether (set! return ..) is there or not. Therefore I'm opting to change the generator code to be minimalistic. That said I regard it as very much irrelevant whether this generator could be applied on any collection, that has conceptually nothing to do with call/cc. Ultraxs (talk) 14:00, 29 July 2011 (UTC)
 * Without this construct, "return" is bound only at first application, so subsequent use of the generator will be for *that* continuation. This will result in undesired behavior. A simple example will suffice: simply first use a generator you defined in an expression like (* 10 (mygenerator)), followed by (* 1 (mygenerator)). Without set! on the return symbol, the second application will use the continuation of the first application, resulting in (* 10 ...) instead of the desired (* 1 ...). Heycarnut (talk) 01:58, 14 January 2012 (UTC)

Hi, I'm also a little new to lisp and am also confused with the second example, namely the  stuff. Surely, since the  variable is assigned the continuation, this continuation cannot accept an argument as input? This should be make clearer for non-lisp programmers such as myself. 81.98.101.31 (talk) 16:53, 6 July 2009 (UTC)
 * Continuations are invoked with arguments, and the arguments are the return values of the call/cc call which created the continuation. 64.81.85.44 (talk) 22:08, 6 August 2009 (UTC)

Why is there an (return 'you-fell-off-the-end) as last statement in procedure control-state? Why not simply 'you-fell-off-the-end? Ultraxs (talk) 14:00, 29 July 2011 (UTC)

Why introducing a name for procedure generator? This name is never used. Again, examples should be minimalistic and free of clutter. Propose to change example to

Ultraxs (talk) 14:00, 29 July 2011 (UTC)

What happens exactly in the second invocation of (generate-digit)? There will be a (call-with-current-continuation resume-here), where resume-here is the inner and previously saved state. Then it appears that the inner call to call/cc just returns with a ... well .. continuation object. But where is this object coming from? Which one is it?. According to explanations above, it must be the outer continuation object, but why? Ultraxs (talk) 14:00, 29 July 2011 (UTC)

Simpler example
I just posted a simpler example to Talk:Continuation of implementing threading with call/cc. The problem with the example in this article is that its hard to read: it mashes up (confuses) the job-dispatching queue with the fork/yield concepts. The Talk:Continuation separates the two, making the code both easier to read, and also making it clear how to write a general job scheduler, (which has nothing at all to do with call/cc). linas (talk) 17:24, 23 August 2009 (UTC)

Exception handling
This aricle should also provide an example of implementing exception handling with call/cc. linas (talk) 17:24, 23 August 2009 (UTC)
 * Why? Does something very special or useful happen? David Spector (user/talk) 15:07, 27 February 2013 (UTC)
 * Continuation passing is an elegant solution to exception handling. See Mitchell's programming languages book for an example. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 07:42, 25 March 2018 (UTC)

Implementation of call/cc
Would anyone care to add to the article some code showing how call/cc is implemented? How does it do what it does? Nothingist (talk) 09:29, 14 May 2010 (UTC)


 * If the underlying implementation is based on continuations, the procedure simply does what its name says: it calls the argument with the current continuation as an argument.


 * If the implementation does not maintain continuations, the effect has to be faked. This is generally impossible to do fully in stack-based implementations because program state is lost when the stack is unwound. Tasty monster (=TS ) 10:58, 14 May 2010 (UTC)
 * Let's assume the former; could you please show how call/cc is implemented? This will help people like me that are trying to implement call/cc in other languages that allow closures and CPS but don't have a native implementation of call/cc. Thank you. Nothingist (talk) 11:40, 14 May 2010 (UTC)

Sure. It would be implemented as follows:

call-with-current-continuation(c) is let k be the current continuation return c(k) end

Tasty monster (=TS ) 17:54, 14 May 2010 (UTC)

Er, not intended for prime time, by the way. The current continuation is of course an ambiguous term, and in this instance it refers to the continuation of the procedure call to call-with-current-continuation. The term "return" which I so quaintly use to express the notion that call-with-current-continuation may return a value, refers to the action of calling the current continuation with the return value as an argument. And now I must go and lie down for a while until my garbage collector completes its essential work. Tasty monster (=TS ) 14:09, 15 May 2010 (UTC)

Google Groups broke
I hate this Google Groups can you change it to a proper Usenet link rather than a web page? --Zzo38 (talk) 08:51, 25 August 2012 (UTC)

C-like semantics
For people that have a background in other programming languages, it might be best to explain call/cc mechanics using classic programming terminology.

Perhaps something like this:


 * call/cc can be thought of as supplying a mechanism which duplicates the current thread in a cooperative multi-tasking environment. We call this mechanism "the current continuation".  In this model of computation, each time the continuation is used, we are instantiating a new cooperative thread, and transferring control to it -- the value passed to the continuation will be the result of call/cc in that thread.


 * For example, in (call/cc (lambda (return-in-cloned-thread) ...)) the name return-in-cloned-thread can be thought of as a routine that creates a new thread which is a copy of the thread that the call/cc appeared in, and in that thread the value passed to return-in-cloned-thread will be the return value from call/cc.


 * When the stack is deep and the computations leading to use of the continuation are complex, an efficient implementation probably implements lazy stack copying and we need to rely on our garbage collector to reclaim threads which can no longer be accessed. In restricted cases, static analysis and/or full stack copying may be a sufficient replacement for these mechanisms.

In other words, explaining call/cc in terms of threading concepts may be useful for people that already understand those threading concepts. (The exact wording was not the point -- I am sure my suggested wording here can be improved on.)

It may be important to draw a distinction between this "threading model" and any "native thread implementation" because they would typically not be the same. But I think this analogy could be useful for some people. Do others (especially frequent users of call/cc) agree? — Preceding unsigned comment added by 173.73.2.10 (talk) 23:14, 31 October 2012 (UTC)


 * I agree, I came here looking for a coroutines example. Which can be written by threads, but with setjmp/longjmp too among other ways. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 07:38, 25 March 2018 (UTC)

English
There are several problems with the english in this page, but I don't understand the page's subject well enough to correct them: "he obtained a scheme program that known as the yin-yang puzzle"; " It was then being customary [2] to show while discussing call/cc"; "Every statements". Masonmilan (talk) 11:12, 29 December 2016 (UTC)

First example revisited
I don't remember well and I do not have Scheme at hand now. But I rewrote the first example as follows:

I am not sure of the (do ...) statement, could anyone check it, please.

I do not think that this example elucidate the use of call/cc because it is based on side effects. That is not the key advantage of a functional language. Although the use of monad composition to explain continuation composition is not easy to write for non pure functional programmers.

I didn't change it in the article, not just because I am not sure of the syntax, but I am also not sure that it is an example that really elucidate the use of call/cc. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 07:33, 25 March 2018 (UTC)

Second example rewritten without call/cc
The second example can be rewritten as follows:

It seems to work like setjmp/longjmp coroutines in C. But is hard to understand. If someone could transform it into one without side effects, i.e. without  and more clear code for human beings, that would be an improvement for the article. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 16:37, 25 March 2018 (UTC)

Ying Yang example is clearer, it can be transformed as follows
The example yin-yang can be transformed as follows replacing   by , this is shorter: the meaning of  is: Although it has the side effects with of calls to  it is a clear example of coroutines. Should we replace the example with the  version above?

I would prefer to rewrite the example building an stream instead of making   calls. Any volunteer to do it? — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 17:13, 25 March 2018 (UTC)

Please extend the Curry-Howard section
Continuations are related with negation in intuitionist logic, but the specific relation with call/cc is not clear enough in this article. Could anyone extend that section, please. — Preceding unsigned comment added by 2806:107E:4:9B98:218:DEFF:FE2B:1215 (talk) 17:56, 25 March 2018 (UTC)

The second example in introduction is wrong
is claimed to be equivalent to, but that only holds when   does call the continuation it receives from call-cc. f can also return a value v normally, in which case the example's final value will be. Vincent Semeria (talk) 19:52, 20 August 2021 (UTC)