[previous] [up] [next]     [index]
Next: Breaks Up: Exceptions and Control Flow Previous: Dynamic Wind

Continuation Marks

To evaluate a sub-expression, MzScheme creates a continuation for the sub-expression that extends the current continuation. For example, to evaluate expr tex2html_wrap_inline100525 in the expression

  (begin 
    expr tex2html_wrap_inline100525 
    expr tex2html_wrap_inline100529 ) 
MzScheme extends the continuation of the begin expression with one continuation frame to create the continuation for expr tex2html_wrap_inline100525 . In contrast, expr tex2html_wrap_inline100529 is in tail position for the begin expression, so its continuation is the same as the continuation of the begin expression.

A continuation mark is a keyed mark in a continuation frame. A program can install a mark in the first frame of its current continuation, and it can extract the marks from all of the frames in its current continuation. Continuation marks support debuggers and other program-tracing facilities, because continuation frames roughly correspond to stack frames in traditional languages. For example, a debugger can annotate a source program to store continuation marks that relate each expression to its source location; when an exception occurs, the marks are extracted from the current continuation to produce a ``stack trace'' for the exception.

The list of continuation marks for a key k and a continuation C that extends C tex2html_wrap_inline100535 is defined as follows:

The mark list for the empty continuation is null for all keys.

The with-continuation-mark form installs a mark on the first frame of the current continuation:

  (with-continuation-mark key-expr mark-expr 
    body-expr) 
The key-expr, mark-expr, and body-expr expressions are evaluated in order. After key-expr is evaluated to obtain a key and mark-expr is evaluated to obtain a mark, the key is mapped to the mark in the current continuation's initial frame. If the frame already has a mark for the key, it is replaced. Finally, the body-expr is evaluated; the continuation for evaluating body-expr is the continuation of the with-continuation-mark expression (so the result of the body-expr is the result of the with-continuation-mark expression, and body-expr is in tail position for the with-continuation-mark expression).

The current-continuation-marks procedure extracts the complete set of continuation marks from the current continuation:

The continuation-mark-set->list procedure extracts mark values for a particular key from a continuation mark set:

Examples:

  (define (extract-current-continuation-marks key) 
     (continuation-mark-set->list 
      (current-continuation-marks) 
      key))

(with-continuation-mark 'key 'mark (extract-current-continuation-marks 'key)) ; => '(mark)

(with-continuation-mark 'key1 'mark1 (with-continuation-mark 'key2 'mark2 (list (extract-current-continuation-marks 'key1) (extract-current-continuation-marks 'key2)))) ; => '((mark1) (mark2))

(with-continuation-mark 'key 'mark1 (with-continuation-mark 'key 'mark2 ; replaces the previous mark (extract-current-continuation-marks 'key)))) ; => '(mark2)

(with-continuation-mark 'key 'mark1 (list ; continuation extended to evaluate the argument (with-continuation-mark 'key 'mark2 (extract-current-continuation-marks 'key)))) ; => '((mark1 mark2))

(let loop ([n 1000]) (if (zero? n) (extract-current-continuation-marks 'key) (with-continuation-mark 'key n (loop (sub1 n))))) ; => '(1)

In the final example, the continuation mark is set 1000 times, but extract-current-continuation-marks returns only one mark value. Because loop is called tail-recursively, the continuation of each call to loop is always the continuation of the entire expression. Therefore, the with-continuation-mark expression replaces the existing mark each time rather than adding a new one.

Whenever MzScheme creates an exception record, it fills the continuation-marks field with the value of (current-continuation-marks), thus providing a snapshot of the continuation marks at the time of the exception.

When a continuation procedure returned by call-with-current-continuation is invoked, it restores the captured continuation, and also restores the marks in the continuation's frames to the marks that were present when call-with-current-continuation was invoked.


[previous] [up] [next]     [index]
Next: Breaks Up: Exceptions and Control Flow Previous: Dynamic Wind

PLT