Question

Both of the following code blocks should (in my mind) be infinite loops

This works

(define call/cc call-with-current-continuation)

(define l 0)
(define i 0)

((lambda ()
   (call/cc
    (lambda (k)
      (set! l k)))
   (write i)
   (newline)
   (set! i (+ i 1))
   (l "ignore")))

This does not work:

(define call/cc call-with-current-continuation)

(define l 0)
(define i 0)

(begin
   (call/cc
    (lambda (k)
      (set! l k)))
   (write i)
   (newline)
   (set! i (+ i 1))
   (l "ignore"))

The only difference is one uses a lambda and one uses a begin block. Why does the second block of code not work?

Thanks

Was it helpful?

Solution

In the second case, the begin splices its arguments into the top-level. Note that there are two kinds of begin: if it's in an expression position, it just sequences operations one after the other. The second kind (which is what you have) will splice all of its arguments into the surrounding context.

The spliced call/cc expression's continuation is actually the empty continuation, since each top-level expression is evaluated separately (i.e., in the empty continuation). You can check this by putting a let around the begin, which forces it to be in an expression position. Then it will infinite loop like you expect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top