next up previous
Next: Informal Development Up: Application Previous: Parser Generation

Non-local Exits

A typical application of control operators is to provide non-local exits, similar to exceptions. The following program which computes the product of the elements of a list and immediately returns 0 if any element of the list is 0 serves as an example.

(define (product xs)
  (call-with-current-continuation
   (lambda (c)
     (let loop ((xs xs))
       (cond
        ((null? xs) 1)
        ((zero? (car xs)) (c 0))
        (else (* (car xs) (loop (cdr xs)))))))))
If xs is dynamic, binding-time analysis (slightly modified wrt. [7]) yields the following two-level code (see below for a formal definition of two-level terms):
(define (product xs)
  (call-with-current-continuation
   (lambda (c : d -> d)
     (let loop ((xs xs))
       (_cond
        ((_null? xs) (_lift 1))
        ((_zero? (_car xs)) (@ c (_lift 0)))
        (else (_* (_car xs) (loop (_cdr xs)))))))))
Apparently, the call-with-current-continuation can be executed statically, at specialization time, with a continuation c, which maps dynamic to dynamic (code to code). However, the effect is disastrous: The specializer starts constructing a variant product-0 of product, captures the continuation, and continues generating a specialized function loop-0 for the loop because of the dynamic conditional (_cond ...) [6]. Then it constructs the body of loop-0. As the specializer reaches the first branch of the second conditional ((zero? (car xs))) the captured continuation is applied to 0. Hence, specialization of loop-0 is indefinitely suspended and the generated code
(define (product-0 xs) 0)
is clearly wrong.

There are three basic problems in the interaction of call/cc with the specializer.

1.
A captured continuation can only be invoked at specialization time if the ignored part of the continuation of the specializer coincides with a part of the continuation of the interpreter.
2.
No specialization/memoization with respect to a captured continuation should occur as the representation for functions in the specializer may not agree with the representation of the underlying Scheme system.
3.
In general, it is unsafe for continuations to be applied to code as the resulting residual code may contain variables which are used outside of their defining scope. However, dynamically closed code (without free variables with binding time dynamic) is fine.


next up previous
Next: Informal Development Up: Application Previous: Parser Generation
Matt Hurlbut
1998-07-15