10.5 Continuation Marks
See Continuation Frames and Marks and Prompts, Delimited Continuations, and Barriers for general information about continuation marks.
The list of continuation marks for a key k and a continuation C that extends C0 is defined as follows:
If C is an empty continuation, then the mark list is null.
If C’s first frame contains a mark m for k, then the mark list for C is (cons m lst), where lst is the mark list for k in C0.
If C’s first frame does not contain a mark keyed by k, then the mark list for C is the mark list for C0.
The with-continuation-mark form installs a mark on the first frame of the current continuation (see Continuation Marks: with-continuation-mark). Procedures such as current-continuation-marks allow inspection of marks.
Whenever Racket creates an exception record for a primitive exception, 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 or call-with-composable-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 or call-with-composable-continuation was invoked.
procedure
(continuation-marks cont [prompt-tag]) → continuation-mark-set?
cont : (or/c continuation? thread? #f)
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
procedure
(current-continuation-marks [prompt-tag])
→ continuation-mark-set?
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
(call-with-current-continuation (lambda (k) (continuation-marks k prompt-tag)) prompt-tag)
procedure
(continuation-mark-set->list mark-set key-v [ prompt-tag]) → list? mark-set : (or/c continuation-mark-set? #f) key-v : any/c
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
Changed in version 8.0.0.1 of package base: Changed to allow mark-set as #f.
procedure
(continuation-mark-set->list* mark-set key-list [ none-v prompt-tag]) → (listof vector?) mark-set : (or/c continuation-mark-set? #f) key-list : (listof any/c) none-v : any/c = #f
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
Changed in version 8.0.0.1 of package base: Changed to allow mark-set as #f.
procedure
(continuation-mark-set->iterator mark-set key-list [ none-v prompt-tag]) → (-> (values (or/c vector? #f) procedure?)) mark-set : (or/c continuation-mark-set? #f) key-list : (listof any/c) none-v : any/c = #f
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
Added in version 7.5.0.7 of package base.
Changed in version 8.0.0.1: Changed to allow mark-set as #f.
procedure
(continuation-mark-set-first mark-set key-v [ none-v prompt-tag]) → any mark-set : (or/c continuation-mark-set? #f) key-v : any/c none-v : any/c = #f
prompt-tag : continuation-prompt-tag? = (default-continuation-prompt-tag)
The result is produced in (amortized) constant time. Typically, this result can be computed more quickly using continuation-mark-set-first than using continuation-mark-set->list or by using continuation-mark-set->iterator and iterating just once.
Although #f and (current-continuation-marks prompt-tag) are equivalent for mark-set, providing #f as mark-set can enable shortcuts that make it even faster.
procedure
(call-with-immediate-continuation-mark key-v proc [ default-v]) → any key-v : any/c proc : (any/c . -> . any) default-v : any/c = #f
This function could be implemented with a combination of with-continuation-mark, current-continuation-marks, and continuation-mark-set->list*, as shown below, but call-with-immediate-continuation-mark is implemented more efficiently; it inspects only the first frame of the current continuation.
; Equivalent, but inefficient: (define (call-with-immediate-continuation-mark key-v proc [default-v #f]) (define private-key (gensym)) (with-continuation-mark private-key #t (let ([vecs (continuation-mark-set->list* (current-continuation-marks) (list key-v private-key) default-v)]) (proc (vector-ref (car vecs) 0)))))
procedure
(make-continuation-mark-key sym) → continuation-mark-key? sym : symbol?
The optional sym argument, if provided, is used when printing the continuation mark.
procedure
v : any/c
procedure
v : any/c
procedure
(continuation-mark-set->context mark-set) → list?
mark-set : continuation-mark-set?
Conceptually, the stack-trace list is the result of continuation-mark-set->list with mark-set and Racket’s private key for procedure-call marks. The implementation may be different, however, and the results may merely approximate the correct answer. Thus, while the result may contain useful hints to humans about the context of an expression, it is not reliable enough for programmatic use.
A stack trace is extracted from an exception and displayed by the default error display handler (see error-display-handler) for exceptions other than exn:fail:user (see raise-user-error in Raising Exceptions).
> (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 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)))) '((mark2 mark1))
> (let loop ([n 1000]) (if (zero? n) (extract-current-continuation-marks 'key) (with-continuation-mark 'key n (loop (sub1 n))))) '(1)