Talk:Continuation

From Wikipedia, the free encyclopedia
Jump to: navigation, search
WikiProject Computer science (Rated C-class, High-importance)
WikiProject icon This article is within the scope of WikiProject Computer science, a collaborative effort to improve the coverage of Computer science related articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
C-Class article C  This article has been rated as C-Class on the project's quality scale.
 High  This article has been rated as High-importance on the project's importance scale.
 
edit·history·watch·refresh Stock post message.svg To-do list for Continuation:

Here are some tasks you can do:

Delegates as continuations[edit]

I really would have to question whether C# supports continuations in any meaningful form. A C# delegate is little more than a function pointer. (See [1]) MAllerton 19:14, 18 July 2005 (UTC)

The use of delegates as continutations in C# comes from their use in callbacks in asynchronouus invocations.--Carl Hewitt 20:12, 18 July 2005 (UTC)
As usual you're not answering the question. Function pointers can't be full blown continuations by the simple fact that they don't save any part of the state/stack. -- Koffieyahoo 10:38, 20 July 2005 (UTC)
I suggest that you read the documentation on the use of delegates for asynchronous invocation.--Carl Hewitt 16:17, 20 July 2005 (UTC)
Can you provide me with a reference? -- Koffieyahoo 08:50, 21 July 2005 (UTC)
See the following for an example.--Carl Hewitt 21:08, 21 July 2005 (UTC)
Asynchronous Web Services
This describes a call-back mechanism, which only saves state by virtue of all relevant data being contained in an object. Hence, this should not be classified as a continuation (the system itself doesn't save any state). So, a more relevant reference is required to convince me that delegates are continuations. --Koffieyahoo 10:04, 4 August 2005 (UTC)
Moreover so, I'm pretty sure the CLR doesn't allow continuations because the stack context (like in the jvm) can't be reified. Wouter Lievens 10:38, 4 August 2005 (UTC)
What do you mean by a continuation?--Carl Hewitt 10:58, 4 August 2005 (UTC)
The article is pretty clear about what a continuation is. -- Karada 11:01, 4 August 2005 (UTC)
In that case, I don't see a problem with using a delegate for such continuations because it has access to the stack frame.--Carl Hewitt 11:06, 4 August 2005 (UTC)
The idea is that the stack frame is saved, being able to access it is not enough. -- Koffieyahoo 12:11, 19 August 2005 (UTC)
I removed the misleading reference to "state" from the beginning of the article. It now reads as follows:
"In computing, a continuation is a representation of an execution point (for example, the instruction pointer and stack frame). Many languages have constructs that allow a programmer to obtain a pointer to a continuation, and then to resume execution using the pointer at a later point in time."
--Carl Hewitt 15:52, 19 August 2005 (UTC)
I don't see how this solves the problem with C#, in that case it's still just a pointer, and that plainly isn't enough for execution to resume. -- Koffieyahoo 09:31, 23 August 2005 (UTC)
Please see the documentation on delegates.--Carl Hewitt 13:14, 23 August 2005 (UTC)
I've done that, and what I see is a function pointer, which doesn't suffice (no stack frame, no intruction pointer). So please eleborate here. -- Koffieyahoo 15:01, 23 August 2005 (UTC)
C# has delegates which are not the same as the function pointers in Java.--Carl Hewitt 21:57, 23 August 2005 (UTC)
Java doesn't have function pointers. Anyway, C# doesn't even have closures, and you can't have continuations without closures. C#s delegates (which work more or less like function objects in C++) just don't suffice. Cadr 22:15, 23 August 2005 (UTC)


Sorry, I meant say that C# has delegates which are not the same as the function pointers in C++.--Carl Hewitt 22:39, 23 August 2005 (UTC)
Okay, so basically there are four people who think that C# does not have continuations and only one thinks that C# has continuations (based on arguments refuted by the other persons). So, I'm removing it from the article. If we want to add it back we should discuss this here first! -- Koffieyahoo 13:29, 24 August 2005 (UTC)
You can't remove it without quoting from the reference to the documentation on delegates.--Carl Hewitt 14:27, 24 August 2005 (UTC)
I've been trying to find an appropriate reference, e.g., by asking you for one. And nothing has turned up, so I simply don't think you're right. Provide me with a reference before you add it back. Every piece of documentation you and others have come up with shows that delegates are not continuations. -- Koffieyahoo 14:56, 24 August 2005 (UTC)
I provided you with the following reference Asynchronous Web Services
You must quote from this document and possibly from other authorities.--Carl Hewitt 18:45, 24 August 2005 (UTC)
Erm, no. The burden of proof is on you in this case. Are we to find documentation for all the other 1000s of programming languages which don't have continuations? What's so notable about C# that it deserves such special treatment? Cadr 20:03, 24 August 2005 (UTC)
A specific citation has been provided above. Have you read it?--Carl Hewitt 20:37, 24 August 2005 (UTC)
That reference doesn't say anything about continuations, so I don't see what it's meant to prove. I've only skimmed the article, but asynchronous callbacks are not at all the same thing as continuations. Can you show us an example program in C# which shows how you would implement call/cc or some equivalent operation in C#? Cadr 23:00, 24 August 2005 (UTC)
The refernce contains a program that performs this.EndInvoke(asyncResult) which resumes execution of the continuation (stack frame).--Carl Hewitt 23:20, 24 August 2005 (UTC)
The reference does not contain a program that performs a call to EndInvoke (it just mentions EndInvoke breifly without really explaining what it does). In any case, suspeding a thread of execution and then resuming it is not equivalent to a continuation. For one thing, a continuation can be called multiple times with identical results (assuming it has no side effects).Cadr 23:58, 24 August 2005 (UTC)
The refernce contains a program that performs this.EndInvoke(asyncResult) which resumes execution of the continuation (stack frame).--Carl Hewitt 04:35, 25 August 2005 (UTC)
As far as I understand it this.EndInvoke(asyncResult) resumes based on solely on the state of the object, which is subject to change between the creation of the delegate and its invocation. Hence, I still don't believe delegates are full-blown continuations. Anyway it was removed from the article. -- Koffieyahoo 09:09, 6 September 2005 (UTC)
Carl Hewitt, are you doing this on purpose?
C# delegates definitely do NOT constitute continuations. They can be used with lots of multithreaded trickery to IMPLEMENT a continuation library, but they themselves are not continuations. However, C# does have the "yield return" and "yield break" keywords which ARE directly able to provide continuation-like behavior. C# delegates, though, have absolutely nothing to do with it. For anyone that disagrees, please provide a code example. Here is a code example of continuations with yeild return:
IEnumerable CF(int max) {
   for(int i=0; i < max; ++i ) {
      yield return i;
   }
}
If C# indeed suports other sorts of continuations, it should be trivial for one to provide a delegate-based example.
I don't think yield qualifies as a continuation because you can't call it multiple times and expect the same result.

The article continuation states that there is more than one kind of continuation as follows:

Kinds of continuations[edit]

Support for continuations varies widely. A programming language supports re-invocable continuations if a continuation may be invoked repeatedly (even after it has already returned1). Re-invocable continuations were introduced by Peter Landin using his J (for Jump) operator that could perform a nonlocal goto into the middle of a procedure invocation. Re-invocable continutations have also been called "re-entrant" in the MzScheme programming language. However this use of the term "re-entrant" is too easily confused with its use in discussions of multitasking.

At one time Sussman and McDermott thouught that using re-invocable continutations (which they called "Hairy Control Structure") was the solution to the AI control structure problems that had originated in Planner. Carl Hewitt et. al. developed message passing as an alternative solution in the Actor model. Guy Steele and Gerry Sussman then developed in the continuations in Scheme in their attempt to understand the Actor model.

A more limited kind is the escape continuation that may be used to escape the current context to a surrounding one. Many languages which do not explicitly support continuations support exception handling, which is equivalent to escape continuations and can be used for the same purposes. C's setjmp and longjmp are also equivalent: they can only be used to unwind the stack. Escape continuations can also be used to implement tail-call optimization.

--Carl Hewitt 04:30, 25 August 2005 (UTC)

OK, then why not use exception handling in C# to demonstrate it's level of support for continuations instead of this more obscure stuff? Cadr 19:24, 26 August 2005 (UTC)
Anynchronous invocation is a more interesting use of continuations in C# than exception handling.--Carl Hewitt 00:58, 27 August 2005 (UTC)
When people say "support for continuations" they usually mean full continuations, since this is what distinguishes a notable subset of languages (e.g. Scheme) from the vast bulk of languages. "Escape continuations" aka exceptions are not remarkable, since most high-level languages support them. --FOo 21:42, 26 August 2005 (UTC)
In a encyclopedia article, it is useful to discuss the full range of continuations. What do you mean by a full continuation?--Carl Hewitt 00:58, 27 August 2005 (UTC)
A full continuation can be invoked multiple times. Languages which are said to "support" continuations are usually expected to have something like call-with-current-continuation, or perhaps as an alternative an easy method of writing programs in continuation passing style (I'm thinking of Haskell here). Really, any language can be said to support continuations. After all, if you are a masochist, you can write a C program in CPS and then play around with continuations as you please. Indeed, it's not particularly difficult to write CPS C code automatically, as Scheme compilers such as Chicken demonstrate. Asking whether a language supports continuations is a bit like asking whether it supports object oriented programming. The real question is "does the language support continuation passing style without a lot of hard work and/or the use of obscure language features?"
One more thing, Carl. Are you saying that asynchronous method invocation doesn't offer anything closer to full continuations than the exception mechanism? If so, it would be far better to use the exception mechanism as an example since it's much easier to understand (regardless of how interesting it may or may not be). Cadr 00:22, 3 September 2005 (UTC)
On reconsideration, I now beleive that it is better to remove the C# delegates from the article so I have done so.--Carl Hewitt 01:12, 3 September 2005 (UTC)

Python continuations?[edit]

Python doesn't have an explicit "continuation object" which you can store and reclaim state from/to. However, in the current version of Python (2.4) you have "generators"; they are resumable functions which return a value using the "yield" statement. Does that qualify as a continuation? See [[2]] for examples of use.--Larry Hastings 16:46, 15 March 2006 (UTC)

Generators don't qualify as continuations. Tim Peters wrote a wonderful mini-essay on how Python generators, coroutines, and continuations relate to each other, but the short version is:
  • Generators represent a single frozen stack frame, while continuations represent a complete call stack.
  • A generator's frame gets resumed on top of its caller, and returns back to it, while a continuation completely replaces its caller's stack (and thus cannot "return").
  • You cannot capture or resume previous states of a generator, but you can invoke continuations from any time in the past, whenever you like, as many times as you like.
--Piet Delport 16:45, 16 March 2006 (UTC)

Example[edit]

I've added the scheme example from Tim Peters's linked posting. This article (an continuations in general) didn't make any sense until I read a concrete example. —The preceding unsigned comment was added by 14:38, 10 July 2006 (talkcontribs) Gene Thomas.

An example in a widely-used language would be even better! 87.187.54.239 11:15, 13 March 2007 (UTC)
Isn't Scheme the most widely used language with standard first-class continuations? Perhaps Ruby has them now and is more widely known than Scheme, but I'm not convinced a Ruby example would be any better than the Scheme example. --Malirath (talk) 20:28, 6 December 2007 (UTC)

Use of closures and continuation-passing style to implement call/cc[edit]

The article currently contains the following paragraph:

In any language which supports anonymous closures, it is possible to write programs in continuation passing style and manually implement call/cc. This is a particularly common strategy in Haskell, where it is easy to construct a "continuation passing monad".

I do not see why the closures would have to be anonymous as it is obviously possible (albeit tedious) to name all continuations. Also, while you can program using CPS in every language with closures, I am not sure whether this really is practical without guaranteed tail-call elimination, so I think this should at least be mentioned. — Tobias Bergemann 08:32, 15 August 2006 (UTC)

Right, the naming of closures is completely orthogonal.
I don't think it's necessary to mention tail-call elimination, though. In strict languages, it's very simple to prevent inefficient tail calls using a trampoline, and in pure, lazy languages like Haskell, the very notion of tail-call elimination becomes ill-defined (since there isn't really any conventional, implicit call stack to do the elimination on). --Piet Delport 22:32, 16 August 2006 (UTC)

Don't start with Scheme!![edit]

I don't think the initial examples should be in Scheme. I don't think this is the best for understanding for the vast majority of programmers. I myself program for a living, and I totally balked at the Scheme intro, not grasping one single thing of what it tries to explain (The same goes for Closure (computer science), using Lisp). If one look at Coroutines, this starts off with some nice pseudocode, immediately understandable for anyone having the slightest interest in computer languages, adaptable to one's preferred universe. —Preceding unsigned comment added by 84.208.115.107 (talkcontribs)

I fully disagree with that. As a self-taught, working programmer who started with C, if you want to understand these sorts of topics (which you should), you need to do your homework & learn the vernaculars. (Or...er...the opposite of the vernacular, I suppose.) While there may not be a lingua franca of computer science, Scheme is one of those languages that is close. --Malirath 21:00, 11 September 2006 (UTC)
Hear, hear. --Piet Delport 22:30, 11 September 2006 (UTC)
It also strikes me that pseudocode means that nobody except the author can be certain what it means. Sticking to R*RS Scheme, however, ensures that an example is as clear as it can be. Nigh anyone who can read Wikipedia can read the standard. --Malirath 02:35, 18 September 2006 (UTC)

Although I am not a Scheme user (I studied it years ago, but for work, I write mostly in Python) I think that ideas like this are better illustrated with Scheme or Lisp than with C-ish languages. A Lisp-oid language shows explicitly where the lexical contours are. In a subject such as continuations, this is essential. --FOo 03:03, 18 September 2006 (UTC)

Perl re-added[edit]

Piet Delport removed perl with a bogus explanation (the entry refered to Coro, not Coro::Cont, and both Coro and Coro::Cont provide continuations and not just generators). —Preceding unsigned comment added by 85.180.123.88 (talkcontribs)

I'm afraid the Coro module's documentation is mistaken.
Coro::Cont provides generators (despite it calling them "continuations"), and Coro::State (referred to in your edit summary) provides coroutines: neither of them (or anything else i can see in the Coro module) provide first-class continuation support. --Piet Delport 21:52, 24 September 2006 (UTC)
You are mistaken then, Coro::State provides everything you need to implement Continuations, as defined by this article. It provides the same semantics as UNIX ucontext, which is also given as an example.
Most notably, this page is about Continuations, which includes call/cc, first-class continuations, the UNIX ucontext family and Coro::State, which us used to provide a coroutine abstraction in Coro and a more-iterator-like abstraction in Coro::Cont (which still is not limited to generators, the continuation created by Coro::Cont has unlimited extend). Specifically, Coro::State might not provide the full generality of call/cc but it does provide support for storing and resuming continuation, as per the wikipedia definition, which IMHO reflects common definitions of continuations elsewhere. If you remove the perl entry again please state what it lacks compared to e.g. ucontext, state what of the definition it does not fulfill or give another reason why this material is inappropriate for this page (for example, listing all languages supporting continuations might not be useful, although it is useful for a common language like perl). It is quite possible that the page (or the perl module documentation) needs improvements in other respects (definition, applicability), but that should be discussed rather than changes simply reverted. Thanks a lot. —Preceding unsigned comment added by 85.180.123.88 (talkcontribs)
Coro::State only allows you to spawn new coroutines, which is very different from being able to capture the current continuation (like getcontext/swapcontext do).
You are correct in saying that Coro::State does not provide the full generality of call/cc, and this is exactly why it does not belong on this page: if it did, everything in the Coroutine and Generator articles would too.
Before you try to add the Coro module to the article again, please do yourself a favor and try using it to implement something like exceptions, or backtracking. This should make it clear what the difference is between it and full continuation support. --Piet Delport 18:17, 27 September 2006 (UTC)
First, please do not remove it again before at least discussing the points I asked for. Then, as I mentioned, this article is about continuations, not about call/cc. You cannot implement backtracking with Coro::State, nor can you implement backtracking with setcontext/getcontext. You can, however, implement exceptions with both of them. This does not matter, though, as the article talks about Continuation, the concept, not the actual implementation in Scheme. The point of having an article about Continuation is to describe the concept in its generality, not a single example of how it is implemented in specific languages. Coro::State creates and manages obejcts that fit the description of Continuation exactly. Unlimited repeatability is not mentioned, nor required, for continuations in general. You really confuse Continuations (which are scarcely more than coroutines) with call/cc, which offers a specific kind of Continuations (for example, it adds repeatability). It is doubtlessly fitting for this article to not limit itself to the Scheme implementation. For example many peopel are confused by the limitation of call/cc returning only the _current_ continuation. Many people find it easier to create continuations as argument to a function (as e.g. Coro::State does). This *is* already mentione din the article. What happens here is that you enforce a limited view of the concept of Continuations which does not follow form the article, nor, as I think, from the general idea behind what a continuation is (namely an abstraction of the current "instruction pointer" + some state such as local variables, which is named "Continuation". Repeatability is a required thing for a continuation). To repeat it: the article talks about continuations, _not_ call/cc, and Coro::State correct encapsulates continuations as defined by the article. The fact that it doesn't do the same thing as call/cc (because it reverses the argument/return value order and doesn't allow repeatability) is irrelevant as long as it fulfills the requirement for continuations. Specifically, it is different from Generator as its state objects have unlimited lifetime (unlike generators) and unlike coroutines, it has a state object which encapsulates the continuation (which is not required for Coroutines). —Preceding unsigned comment added by 85.180.97.187 (talkcontribs)
Who ever said the article was only about call/cc, or Scheme?
What it is about, anyway, is first-class continuations. This specifically excludes everything that only involves continuations at some hidden, implicit level, because those are so pervasive and ubiquitous that the article would probably have to discuss nearly every feature of almost every programming language in existence. Instead, those features are treated in their own articles (Coroutine, in the Coro module's case).
Now, a few corrections and responses:
  • You can implement backtracking with setcontext/getcontext. In fact, there are language implementations that use setcontext/getcontext not only for that, but for all their first-class continuation support. (GNU Guile, for example[3])
  • You can not implement exceptions using Coro::State or (as far as i can tell from the source code and documentation) anything else in the Coro module. (It allows you to capture/resume the current coroutine, but not any of the (outer, exception-handling) continuations entailed by it.)
  • "[...] call/cc, which offers a specific kind of Continuations (for example, it adds repeatability)." Actually, call/cc need not make any guarantee about the kind or extent ("repeatability") of the continuations obtained by it (unless you're talking about specific definitions, like the one in R5RS[4] (which has no bearing on anything outside of Scheme, of course)). Many non-Scheme languages with call/cc (and some Scheme implementations) place necessary restrictions on the extent of the continuations obtained in certain contexts: for example, when mixtures of C and high-level stack frames are involved.
  • "[...] state objects have unlimited lifetime (unlike generators), and unlike coroutines, it has a state object which encapsulates the continuation (which is not required for Coroutines)." I'm not completely certain about what you mean, here, but by any reasonable interpretation i can come up with, generators do have unlimited lifetimes, and coroutines are required by definition to encapsulate a continuation.
Finally, even if the Coro module did provide first-class continuation support (which it doesn't), i would questioning its encyclopedic merit to begin with, considering that Coro::State comes with a disclaimer saying "This module has not yet been extensively tested, but works on most platforms. Expect segfaults and memleaks", and that it does not seem to have much, if any, actual users. --Piet Delport 08:41, 1 October 2006 (UTC)
I have mentioned this limitation for both ucontext and coro now. Also,e verytime you removed perl you also removed other unrelated edits, please be more careful in the future (but I hope you are now convinced that discussing the full range of continuations as defined by the article itself is better than only disucssing call/cc and variants, which would better be done in a separate page that only talks about call/cc). —Preceding unsigned comment added by 85.180.97.187 (talkcontribs)
I assure you, i endeavour to be very careful with my edits. I did not roll back the other edits accidentally, but because they run counter to Wikipedia's style guideline that list entries should not have trailing periods unless they contain full sentences. --Piet Delport 08:41, 1 October 2006 (UTC)

Similar to fiber?[edit]

There is an article on Fiber (computer science). Fibers appear to be very similar to continuations. If they are the same, perhaps the articles should be merged. If they are not the same, then perhaps a reference and some distinctions should be added to the article. Kevin99 18:04, 21 February 2007 (UTC)

Close; as the article points out, Fibers are essentially coroutines. Any discussion and comparison probably belongs there. --Piet Delport 08:03, 29 April 2007 (UTC)

Delimited continuations[edit]

I've redirected to here. If anyone who understands them could add a section, that'd be good. --Gwern (contribs) 13:14 4 July 2007 (GMT)

Steve Russel's second Lisp interpreter[edit]

Does anyone have a reference for the statement in the article that Steve Russell implemented continuations in his second Lisp interpreter? Kleg 20:01, 31 July 2007 (UTC)

Continuations in web programming[edit]

The section states that there's no consensus yet, however, after looking at the linked argument against, it's pretty clear that the opposition to continuations is a result of a fairly gross misunderstanding of the nature and working of continuations, the argument being, roughly, "let's not bother with continuations, instead let's devise a mechanism which would let us store enough of the state to resume the computation at any point", which is exactly what continuations are. The first linked blog post even goes as far as citing the fact that continuations can supposedly break if the user submits a form multiple times, showing utter confusion and completely missing the fact that preventing that is the very reason continuations are used for web programming.

Given that both the pros and cons arguments linked are fairly insubstantial (just random blogs), I'd propose either either expanding that section into a proper explanation of exact nature of continuations as applied to the web programming, or entirely removing the mention of supposed lack of consensus, as it lacks any serious backup in well-researched publications. mathrick 22:48, 2 October 2007 (UTC)

I for one "invented" a form of continuations in this context in my first web project (at school, in previous century) by using a "hidden=" field in forms sent back to the client to encode "what to do next" and avoid a heavy-weight session controller. I was quite aware of what I was doing though. Reading this, I was curious if anybody published something like that so we can use it in here without writing my WP:OR. In Queinnec's paper, there is a mention of that in the related work section (section 8). I think that some technical details would not hurt in this article, or be too off-topic. That section devotes too much space to this so called controversy, instead of being informative on how continuations may be implemented in a web app. Pcap ping 13:53, 5 September 2009 (UTC)

Who invented call-with-current-continuation?[edit]

Though Dan Friedman is certainly a fan of call/cc, and talks about continuations often, and several chapters of the Essentials of Programming Languages are dedicated to the Continuation Passing Style, he didn't come up with it. Sussman and Steele's original Scheme, as detailed in the lambda papers, had an operator comparable to call/cc. Even so, they didn't come up with it either, exactly, though their Rabbit compiler was the first to convert programs to the continuation passing style as part of the compiliation. This site suggests that Landin may have come up with it, though the site's author is not sure.

The concept of a contination, as opposed to operators such as call/cc that allow one to grab a continuation, has an obscure origin in the early days of computing. I don't really know many details here. 66.170.46.244 (talk) 12:55, 29 June 2008 (UTC)

Please read Carl Hewitt's "Kinds of continuations" comment up above. He addresses some of the early history. linas (talk) 15:25, 22 August 2009 (UTC)

Too complex[edit]

Wow, that's a heavy article. I'm a computer scientist and I had a hard time grasping the summary. 81.15.57.130 (talk) 09:48, 11 September 2008 (UTC)

I concur, this page should be simplified and have examples in pseudocode, so everyone can understand them. Antony Carthy (talk) 09:57, 2 October 2009 (UTC)
I've added the example below. It's a shame it's sitting here in the talk page when it could be illustrating a practical usage in the article. Diego (talk) 10:38, 2 October 2009 (UTC)
Would it possible to have a step by step example of call/cc? I interpreted call/cc g as g trap0. The trap0 argument was propagated down through the function. When the trap0 argument (which is a one parameter function itself) was executed with an argument, it would return to the create point of trap0. So when trap0 3 was called, then the program would jump to call/cc g with the value 3. DetriusXii (talk) 18:09, 30 November 2011 (UTC)

Coroutines/threads implemented from continuations[edit]

During email discussions, Eric Cooper at CMU offered up the below very simple, very elegant example of using call/cc to implement coroutines/threads. I post it here mostly because I think its a very nice programming Design pattern (computer science), combining a queue with call/cc to make it all work. By comparison, googling "coroutine scheme" returns some truly horrid, mind-bendingly bad examples.

This example provides a very nice illustration of "what the heck are continuations good for?" -- because, without examples of their utility, they seem somewhat abstract and pointless. I'd like to see this example in some article somewhere, but not sure which article: this example, though very brief, is still longer than most.


;;; A naive queue for thread scheduling.
;;; It holds a list of continuations "waiting to run".
 
  (define *queue* '())
 
  (define (empty-queue?)
    (null? *queue*))
 
  (define (enqueue x)
    (set! *queue* (append *queue* (list x))))
 
  (define (dequeue)
    (let ((x (car *queue*)))
      (set! *queue* (cdr *queue*))
      x))
 
  ;;; This starts a new thread running (proc).
 
  (define (fork proc)
    (call/cc
     (lambda (k)
       (enqueue k)
       (proc))))
 
  ;;; This yields the processor to another thread, if there is one.
 
  (define (yield)
    (call/cc
     (lambda (k)
       (enqueue k)
       ((dequeue)))))
  
  ;;; This terminates the current thread, or the entire program
  ;;; if there are no other threads left.
 
  (define (thread-exit)
    (if (empty-queue?)
        (exit)
        ((dequeue))))
  ;;; The body of some typical Scheme thread that does stuff:
 
  (define (do-stuff-n-print str)
    (lambda ()
      (let loop ((n 0))
        (format #t "~A ~A\n" str n)
        (yield)
        (loop (1+ n)))))
 
  ;;; Create two threads, and start them running.
  (fork (do-stuff-n-print "This is AAA"))
  (fork (do-stuff-n-print "Hello from BBB"))
  (thread-exit)

Again, thanks to Eric Cooper for above nice example. linas (talk) 15:50, 22 August 2009 (UTC)

p.s. Eric adds that the example was first presented here:
Haynes, C. T., Friedman, D. P., and Wand, M. 1984. Continuations and coroutines. In Proceedings of the 1984 ACM Symposium on LISP and Functional Programming (Austin, Texas, United States, August 06 - 08, 1984). LFP '84. ACM, New York, NY, 293-298.
linas (talk) 16:12, 22 August 2009 (UTC)

Hey, linus, that's a really great example! It showed me exactly how continuations might be used. Just a small point though, shouldn't ((dequeue)) be ((dequeue) nil) so that the continuation get's its argument? On my implementation, at least, the enqueued continuation requires an argument to use as its return-value. --Kristianlm (talk) 06:49, 10 March 2012 (UTC)

Another example: Exceptions (throw, catch)[edit]

Another classic example of the usefulness of continuations is the implementation of exception handlers (throw, catch). I think this would be an excellent addition to this article: so, for example, both Java and C++ implement exceptions, but they do it in a hacky, non-general kind of way. By contrast, it should become very simple if instead one had general-purpose continuations. linas (talk) 17:11, 23 August 2009 (UTC)

Continuations in Lua?[edit]

This article says "In any language which supports closures, it is possible to write programs in continuation passing style and manually implement call/cc."

Well, Lua supports closures, so can anyone give an example on how to implement call/cc in Lua? I'm not talking about Lua's coroutine table. I already know that exists, plus that's for coroutines, which if I understand correctly, can also be implemented using call/cc but they themselves are not call/cc. Nothingist (talk) 12:52, 12 May 2010 (UTC)

In other words, if that excerpt is really true then it would be appropriate to exemplify it, and I think Lua would be a perfect candidate to write an example in since it does have closures but no native call/cc functionality (again, I'm not talking about the coroutine table in Lua). Nothingist (talk) 14:12, 13 May 2010 (UTC)