[racket] Delimited continuations and parameters
TWO DISTINCT ISSUES:
I have encoded the apparent first step in the reduction sequence via submodules.
ISSUE 1: I am disturbed that submodule b is evaluated before submodule a.
ISSUE 2: What is the semantics of parameterize?
#lang racket
(module a racket
(require racket/control)
(define p (make-parameter 0))
(define r (make-parameter 0))
`(a ,
((λ (f)
(parameterize ([p 2])
(parameterize ([r 20])
(f 0))))
(parameterize ([p 1])
(reset
(parameterize ([r 10])
((λ (x) (+ (p) (r)))
(shift f f))))))))
(require (submod "." a))
(module b racket
(require racket/control)
(define p (make-parameter 0))
(define r (make-parameter 0))
`(b ,
((λ (f)
(parameterize ([p 2])
(parameterize ([r 20])
(f 0))))
(parameterize ([p 1])
(λ (zzz) ;; <================= INCLUDING THE parameterize r while not including parameterize p is an arbitrary choice
(reset ;; <--- you accidentally left this one off, though that has no consequences
(parameterize ([r 10])
((λ (x) (+ (p) (r)))
zzz))))))))
(require (submod "." b))
Oleg & Co seem to think it is the "right" choice. It is plain whimsical to insist on this as "right". BECAUSET one could conceive of continuation operations as complete traversals of the continuation all the way to the top (an eager copy semantics/implementation) and a partial copy (lazy copy). That would have been another way -- distinct from the explanation for Racket -- how to view things differently. The explanation for Racket resolves a different issue in a way that Oleg didn't foresee, namely, it interprets parameterize in continuation-global way. From an implementation perspective as well as a threaded perspective, this may make even more sense than Oleg and Co's semantics because you may wish to migrate continuations from one thread to another (or VM to another) and you may just expect to find all parameters there. I have too little experience with threaded programming with parameterizations (other than the default ones) to make any claim here. HOWEVER, ever since I experimented in Scheme 88 with prompts around letrec RHS and Bob Hieb howling in horror, I have learned to be careful when it comes to combinations of classic continuations and delimited continuations. From a system perspective, the former -- whole-sale stacks -- make a lot of sense. From a tricks-and-ponies perspective for programmers, the latter makes equal sense. The combination is neither straightforward nor resolved by plain semantic considerations.
-- Matthias