racket/collects/scribblings/reference/cont-marks.scrbl
Matthew Flatt 39cedb62ed v3.99.0.2
svn: r7706
2007-11-13 12:40:00 +00:00

171 lines
6.7 KiB
Racket

#lang scribble/doc
@require[scribble/struct]
@require["mz.ss"]
@define[(cont n) (make-element "schemevariable"
(list "C" (make-element 'subscript (list (format "~a" n)))))]
@title[#:tag "contmarks"]{Continuation Marks}
@declare-exporting[(lib "scheme/control")]
See @secref["mark-model"] and @secref["prompt-model"] for
general information about continuation marks.
The list of continuation marks for a key @scheme[_k] and a continuation
@scheme[_C] that extends @cont[0] is defined as follows:
@itemize{
@item{If @scheme[_C] is an empty continuation, then the mark list is
@scheme[null].}
@item{If @scheme[_C]'s first frame contains a mark @scheme[_m] for @scheme[_k],
then the mark list for @scheme[_C] is @scheme[(cons @scheme[_m] _lst)],
where @scheme[_lst] is the mark list for @scheme[_k] in @cont[0].}
@item{If @scheme[_C]'s first frame does not contain a mark keyed by
@scheme[_k], then the mark list for @scheme[_C] is the mark list for
@cont[0].}
}
The @scheme[with-continuation-mark] form installs a mark on the first
frame of the current continuation (see @secref["wcm"]). Procedures
such as @scheme[current-continuation-marks] allow inspection of marks.
Whenever Scheme creates an exception record for a primitive exception,
it fills the @scheme[continuation-marks] field with the value of
@scheme[(current-continuation-marks)], thus providing a snapshot of
the continuation marks at the time of the exception.
When a continuation procedure returned by
@scheme[call-with-current-continuation] or
@scheme[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
@scheme[call-with-current-continuation] or
@scheme[call-with-composable-continuation] was invoked.
@defproc[(continuation-marks [cont continuation?]
[prompt-tag prompt-tag? (default-continuation-prompt-tag)])
continuation-mark-set?]{
Returns an opaque value containing the set of continuation marks for
all keys in the continuation @scheme[cont] up to the prompt tagged by
@scheme[prompt-tag]. If @scheme[cont] is an escape continuation (see
@secref["prompt-model"]), then the current continuation must extend
@scheme[cont], or the @exnraise[exn:fail:contract]. If @scheme[cont]
was not captured with respect to @scheme[prompt-tag] and does not
include a prompt for @scheme[prompt-tag], the
@exnraise[exn:fail:contract].}
@defproc[(current-continuation-marks [prompt-tag prompt-tag? (default-continuation-prompt-tag)])
continuation-mark-set?]{
Returns an opaque value containing the set of continuation marks for
all keys in the current continuation up to @scheme[prompt-tag]. In
other words, it produces the same value as
@schemeblock[
(call-with-current-continuation
(lambda (k)
(continuation-marks k prompt-tag))
prompt-tag)
]}
@defproc[(continuation-mark-set->list
[mark-set continuation-mark-set?]
[key-v any/c]
[prompt-tag prompt-tag? (default-continuation-prompt-tag)])
list?]{
Returns a newly-created list containing the marks for @scheme[key-v]
in @scheme[mark-set], which is a set of marks returned by
@scheme[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 @scheme[prompt-tag]..}
@defproc[(continuation-mark-set->list*
[mark-set continuation-mark-set?]
[key-v any/c]
[none-v any/c #f]
[prompt-tag prompt-tag? (default-continuation-prompt-tag)])
(listof vector?)]{
Returns a newly-created list containing vectors of marks in
@scheme[mark-set] for the keys in @scheme[key-list], up to
@scheme[prompt-tag]. The length of each vector in the result list is
the same as the length of @scheme[key-list], and a value in a
particular vector position is the value for the corresponding key in
@scheme[key-list]. Values for multiple keys appear in a single vector
only when the marks are for the same continuation frame in
@scheme[mark-set]. The @scheme[none-v] argument is used for vector
elements to indicate the lack of a value.}
@defproc[(continuation-mark-set-first
[mark-set (or/c continuation-mark-set? false/c)]
[key-v any/c]
[prompt-tag prompt-tag? (default-continuation-prompt-tag)])
any]{
Returns the first element of the list that would be returned by
@scheme[(continuation-mark-set->list (or mark-set
(current-continuation-marks prompt-tag)) key-v prompt-tag)], or
@scheme[#f] if the result would be the empty list. Typically, this
result can be computed more quickly using
@scheme[continuation-mark-set-first].}
@defproc[(continuation-mark-set? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a mark set created by
@scheme[continuation-marks] or @scheme[current-continuation-marks],
@scheme[#f] otherwise.}
@defproc[(continuation-mark-set->context
[mark-set continuation-mark-set?])
list?]{
Returns a list representing a ``@index["stack dump"]{@as-index{stack
trace}}'' for @scheme[mark-set]'s continuation. The list contains
pairs, where the @scheme[car] of each pair contains either @scheme[#f]
or a symbol for a procedure name, and the @scheme[cdr] of each pair
contains either @scheme[#f] or a @scheme[srcloc] value for the
procedure's source location (see @secref["linecol"]); the
@scheme[car] and @scheme[cdr] are never both @scheme[#f].
The stack-trace list is the result of
@scheme[continuation-mark-set->list] with @scheme[mark-set] and
Scheme's private key for procedure-call marks. A stack trace is
extracted from an exception and displayed by the default error display
handler (see @scheme[current-error-display-handler]) for exceptions other than
@scheme[exn:fail:user] (see @scheme[raise-user-error] in
@secref["errorproc"]).}
@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))
(with-continuation-mark 'key1 'mark1
(with-continuation-mark 'key2 'mark2
(list
(extract-current-continuation-marks 'key1)
(extract-current-continuation-marks 'key2))))
(with-continuation-mark 'key 'mark1
(with-continuation-mark 'key 'mark2 (code:comment @t{replaces the previous mark})
(extract-current-continuation-marks 'key)))
(with-continuation-mark 'key 'mark1
(list (code:comment @t{continuation extended to evaluate the argument})
(with-continuation-mark 'key 'mark2
(extract-current-continuation-marks 'key))))
(let loop ([n 1000])
(if (zero? n)
(extract-current-continuation-marks 'key)
(with-continuation-mark 'key n
(loop (sub1 n)))))
]