► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 10 | Control Flow

10.1 | Multiple Values
10.2 | Exceptions
10.3 | Delayed Evaluation
10.4 | Continuations
10.5 | Continuation Marks
10.6 | Breaks
10.7 | Exiting

On this page:

continuation-marks
current-continuation-marks
continuation-mark-set->list
make-continuation-mark-key
continuation-mark-set->list*
continuation-mark-set-first
call-with-immediate-continuation-mark
continuation-mark-key?
continuation-mark-set?
continuation-mark-set->context

top ← prev up next →

#### 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)

Returns an opaque value containing the set of continuation marks for all keys in the continuation cont (or the current continuation of cont if it is a thread) up to the prompt tagged by prompt-tag. If cont is #f, the resulting set of continuation marks is empty. If cont is an escape continuation (see Prompts, Delimited Continuations, and Barriers), then the current continuation must extend cont, or the exn:fail:contract exception is raised. If cont was not captured with respect to prompt-tag and does not include a prompt for prompt-tag, the exn:fail:contract exception is raised. If cont is a dead thread, the result is an empty set of continuation marks.

> procedure (current-continuation-marks [prompt-tag])
> → continuation-mark-set?
> | prompt-tag |  | : |  | continuation-prompt-tag?
> |  |  | = |  | (default-continuation-prompt-tag)

Returns an opaque value containing the set of continuation marks for all keys in the current continuation up to prompt-tag. In other words, it produces the same value as

> (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 : continuation-mark-set?
> key-v : any/c
> | prompt-tag |  | : |  | continuation-prompt-tag?
> |  |  | = |  | (default-continuation-prompt-tag)

Returns a newly-created list containing the marks for key-v in mark-set, which is a set of marks returned by current-continuation-marks. The result list is truncated at the first point, if any, where continuation frames were originally separated by a prompt tagged with prompt-tag.

> procedure (make-continuation-mark-key) → continuation-mark-key?
> (make-continuation-mark-key sym) → continuation-mark-key?
> sym : symbol?

Creates a continuation mark key that is not equal? to the result of any other value (including prior and future results from make-continuation-mark-key). The continuation mark key can be used as the key argument for with-continuation-mark or accessor procedures like continuation-mark-set-first. The mark key can be chaperoned or impersonated, unlike other values that are used as the mark key.

The optional sym argument, if provided, is used when printing the continuation mark.

> > procedure
> > (continuation-mark-set->list* |  | mark-set |  |  |  |
> > |  | key-list |  |  |  |
> > | [ | none-v |  |  |  |
> > |  | prompt-tag]) |  | → |  | (listof vector?)
> mark-set : continuation-mark-set?
> key-list : (listof any/c)
> none-v : any/c = #f
> | prompt-tag |  | : |  | continuation-prompt-tag?
> |  |  | = |  | (default-continuation-prompt-tag)

Returns a newly-created list containing vectors of marks in mark-set for the keys in key-list, up to prompt-tag. The length of each vector in the result list is the same as the length of key-list, and a value in a particular vector position is the value for the corresponding key in key-list. Values for multiple keys appear in a single vector only when the marks are for the same continuation frame in mark-set. The none-v argument is used for vector elements to indicate the lack of a value.

> > 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)

Returns the first element of the list that would be returned by (continuation-mark-set->list (or mark-set (current-continuation-marks prompt-tag)) key-v prompt-tag), or none-v if the result would be the empty list. Typically, this result can be computed more quickly using continuation-mark-set-first than using continuation-mark-set->list.

> > 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

Calls proc with the value associated with key-v in the first frame of the current continuation (i.e., a value that would be replaced if the call to call-with-immediate-continuation-mark were replaced with a with-continuation-mark form using key-v as the key expression). If no such value exists in the first frame, default-v is passed to proc. The proc is called in tail position with respect to the call-with-immediate-continuation-mark call.

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 (continuation-mark-key? v) → boolean?
> v : any/c

Returns #t if v is a mark key created by make-continuation-mark-key, #f otherwise.

> procedure (continuation-mark-set? v) → boolean?
> v : any/c

Returns #t if v is a mark set created by continuation-marks or current-continuation-marks, #f otherwise.

> procedure (continuation-mark-set->context mark-set) → list?
> mark-set : continuation-mark-set?

Returns a list representing an approximate “stack trace” for mark-set’s continuation. The list contains pairs, where the car of each pair contains either #f or a symbol for a procedure name, and the cdr of each pair contains either #f or a srcloc value for the procedure’s source location (see Counting Positions, Lines, and Columns); the car and cdr are never both #f.

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).

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 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)

top ← prev up next →