simple question about call/cc

38 views
Skip to first unread message

Tim Meehan

unread,
Dec 7, 2020, 9:26:20 PM12/7/20
to Racket Users
I've read a lot about call/cc, and each time wind up just moving on. So this is an early New Year's resolution: getting a better understanding of it. 

According to Wikipedia's page on continuations, the continuation of the statement:

((call/cc f) e2)

is:

(lambda (c) (c e2))

#lang racket
(define ret #f)
(define ret2 (lambda (c) (add1 c)))

(add1
 (call/cc
  (lambda (k)
    (set! ret k) ;; Now ret should be equivalent to ret2.
    2)))

(ret 9) ;; Why does this print twice?
(ret2 5) ;; This only prints once, like I would have expected.

Justin Zamora

unread,
Dec 7, 2020, 10:56:33 PM12/7/20
to Tim Meehan, Racket Users
The duplication is because you're evaluating the expression at top
level, so the repl is part of the continuation. The continuation isn't
(lambda (c) (c e2); it's actually something like (lambda (c)
(evaluate-in-repl (c e2)). So when you run (ret 9), you're actually
re-running the repl you had when you evaluated the expression, which
leads to the duplication.

To avoid this, put the expression in a procedure:

#lang racket
(define ret #f)
(define ret2 (lambda (c) (add1 c)))

(define (haha)
(add1
(call/cc
(lambda (k)
(set! ret k) ;; Now ret should be equivalent to ret2.
2))))

Then you get what you expect, because the continuation is delimited by
the procedure definition:

Welcome to DrRacket, version 7.8 [3m].
Language: racket, with debugging; memory limit: 128 MB.
> (haha)
3
> (ret 9)
10
> (ret2 5)
6
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CACgrOx%2BnXZpQv_MbDwdAZJSGpMiD%2BE1gB4YH8Rsb_y3%3D6RaAnQ%40mail.gmail.com.

Laurent

unread,
Dec 8, 2020, 5:52:08 AM12/8/20
to Tim Meehan, Racket Users
Tim, if you paste your code in the definitions in DrRacket (with the #lang racket line), and run it (as a module, thus), you obtain this in the interactions window:
3
10
6

The `3` is because of the `(add1 (call/cc ... 2)))` expression, which is reduced to `(add1 2)` with the side effect of recording the continuation in `ret`.
The `10` corresponds to `(ret 9)`.


--
Reply all
Reply to author
Forward
0 new messages