Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scheme: What is the difference between define and let when used with continutation

I'm wondering the difference between the two following code:

(define cont2 #f) 
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f)

and

(let [(cont #f)]
  (call/cc (lambda (k) (set! cont k)))
  (display "*")
  (cont #f))

In my opinion, the correct behavior of these two programs should be printing '*' infinitely. However, the first one only prints one '*' and exits, while the second one gives the correct behavior.

So I'm confused. Is there something special done with define or the continuation is not what I thought - all the following programs until the end of the program, it seems to have a boundary or something.

Another guess is that the top-level of environment is special treated, like this:

(define (test)
  (define cont2 #f) 
  (call/cc (lambda (k) (set! cont2 k)))
  (display "*")
  (cont2 #f))
(test)

This works, but why?

Thank you for your help!

like image 460
Shiva Wu Avatar asked Dec 08 '22 13:12

Shiva Wu


1 Answers

In Racket, each top-level expression is wrapped with a prompt.

Since call/cc only "captures the current continuation up to the nearest prompt", in your first example, none of the other top-level expressions are captured, so applying cont2 to #f results in just #f.

Also, wrapping the first example in begin won't change things since a top-level begin implicitly splices its contents as if they were top-level expressions.

like image 160
stchang Avatar answered Apr 30 '23 10:04

stchang