5

Continuation describes what happens next with some value, right? Isn't that just a function that takes a value and does some computation?

(+ (* 2 3) 5)

the continuation of (* 2 3) is (+ _ 5)

(define k (lambda (v) (+ v 5)))

What is the point of using call/cc in here and not using the function k ?

Drew
  • 29,895
  • 7
  • 74
  • 104
ayhid
  • 475
  • 2
  • 10
  • You don't use `call/cc` whose argument *is* taking the current continuation (as a function). Edit your question to use `call/cc`! Read wikipage on [continuation](http://en.wikipedia.org/wiki/Continuation) – Basile Starynkevitch Aug 29 '13 at 22:40
  • I'm not using call/cc, I'm using an equivalent function represents the continuation? – ayhid Aug 29 '13 at 22:47
  • Continuation is syntactically a function but it represents a control transfer. Its call protocol is different than a function's - it's supposed never to return. – Will Ness Aug 31 '13 at 17:03

3 Answers3

6

True. All programs have continuations until it halts. One continuation is usually one step in the calculation done by the underlying implementation.

Your example:

(+ (* 2 3) 5)

The combination + is dependent on the combination * to finish first. Thus (+ result 5) is indeed the continuation of (* 2 3). It's not a procedure in this context though. The usefulness of call/cc is when you have an continuation you regret and want to do something else instead or you want to come back to this at a later time. Lets do the first:

(define g 0)
(call/cc 
  (lambda (exit)
    (/ 10 (if (= g 0) (exit +Inf.0) g))))

Clearly, there is a division which is the continuation when the result of the if is done, but since exit is run the whole thing gets short circuited to return +Inf.0.

How would you do that with a procedure without getting it to do the division afterward? In this style, you can't.

It isn't really magic since Scheme converts your code to Continuation Passing Style(=CPS) and in CPS call/cc is no special. It's not trivial writing code in CPS.

Here's the CPS definition of call/cc

(define (kcall/cc k consumer)
  (consumer k (lambda (ignore v) (k v))))
Sylwester
  • 47,942
  • 4
  • 47
  • 79
4

Congratulations! You've just invented continuation-passing style! The only difference between what you've done and call/cc is that call/cc does it automatically, and doesn't require you to restructure your code.

John Clements
  • 16,895
  • 3
  • 37
  • 52
2

A 'continuation' is the entire future of a computation. Every point in a computation has a continuation which, in naive terms, you can think of as the current program-counter and current stack. The Scheme call/cc function conveniently captures the current configuration and packages it up into a function. When you invoke that function you revert back to that point in the computation. Thus, a continuation is very different from a function (but the continuation function is, well, a function).

There are two common cases where one typically sees call/cc applied:

  1. non-local exit. You establish a continuation, do some computation, to abruptly end the computation you invoke the continuation.

  2. restart/reenter a computation. In this case you save the continuation and then call it again as you please.

Here is an example for case #1:

(begin
  ;; do stuff
  (call/cc (lambda (k)
              ;; do more

             ;; oops, must 'abort'
             (k 'ignore)))
  ;; continue on
  )

And here is an example for case #2:

> (define c #f)
> (let ((x 10))
   (display (list (+ 1 (call/cc (lambda (k) (set! c k) x))) 111))
   (display " more"))
(11 111) more
> (c 20)
(21 111) more
> (c 90)
(91 111) more

For this case #2 is it worth noting that the continuation brings you back to the top-level read-eval-print loop - which gives you a chance to re-invoke the continuation in this example!

GoZoner
  • 67,920
  • 20
  • 95
  • 145