87 lines
3.7 KiB
Racket
87 lines
3.7 KiB
Racket
#lang scribble/doc
|
|
@(require "mz.rkt"
|
|
(for-label racket/unsafe/undefined))
|
|
|
|
@title[#:tag "unsafe-undefined"]{Unsafe Undefined}
|
|
|
|
@note-lib-only[racket/unsafe/undefined]
|
|
|
|
The constant @racket[unsafe-undefined] is used internally as a
|
|
placeholder value. For example, it is used by @racket[letrec] as a
|
|
value for a variable that has not yet been assigned a value. Unlike
|
|
the @racket[undefined] value exported by @racketmodname[racket/undefined],
|
|
however, the @racket[unsafe-undefined] value should not leak as the
|
|
result of a safe expression, and it should not be passed as an optional
|
|
argument to a procedure (because it may count as ``no value provided'').
|
|
Expression results that potentially
|
|
produce @racket[unsafe-undefined] can be guarded by
|
|
@racket[check-not-unsafe-undefined], so that an exception can be
|
|
raised instead of producing an @racket[undefined] value.
|
|
|
|
The @racket[unsafe-undefined] value is always @racket[eq?] to itself.
|
|
|
|
@history[#:added "6.0.1.2"
|
|
#:changed "6.90.0.29" @elem{Procedures with optional arguments
|
|
sometimes use the @racket[unsafe-undefined]
|
|
value internally to mean ``no argument supplied.''}]
|
|
|
|
@defthing[unsafe-undefined any/c]{
|
|
|
|
The unsafe ``undefined'' constant.
|
|
|
|
See above for important constraints on the use of @racket[unsafe-undefined].}
|
|
|
|
|
|
@defproc[(check-not-unsafe-undefined [v any/c] [sym symbol?])
|
|
(and/c any/c (not/c (one-of/c unsafe-undefined)))]{
|
|
|
|
Checks whether @racket[v] is @racket[unsafe-undefined], and raises
|
|
@racket[exn:fail:contract:variable] in that case with an error message
|
|
along the lines of ``@racket[sym]: undefined; use before
|
|
initialization.'' If @racket[v] is not @racket[unsafe-undefined],
|
|
then @racket[v] is returned.}
|
|
|
|
@defproc[(check-not-unsafe-undefined/assign [v any/c] [sym symbol?])
|
|
(and/c any/c (not/c (one-of/c unsafe-undefined)))]{
|
|
|
|
The same as @racket[check-not-unsafe-undefined], except that the error
|
|
message (if any) is along the lines of ``@racket[sym]: undefined;
|
|
assignment before initialization.''}
|
|
|
|
|
|
@defproc[(chaperone-struct-unsafe-undefined [v any/c]) any/c]{
|
|
|
|
Chaperones @racket[v] if it is a structure (as viewed through some
|
|
@tech{inspector}). Every access of a field in the structure is checked
|
|
to prevent returning @racket[unsafe-undefined]. Similarly, every
|
|
assignment to a field in the structure is checked (unless the check
|
|
disabled as described below) to prevent assignment of a field whose
|
|
current value is @racket[unsafe-undefined].
|
|
|
|
When a field access would otherwise produce @racket[unsafe-undefined]
|
|
or when a field assignment would replace @racket[unsafe-undefined], the
|
|
@racket[exn:fail:contract] exception is raised.
|
|
|
|
The chaperone's field-assignment check is disabled whenever
|
|
@racket[(continuation-mark-set-first #f
|
|
prop:chaperone-unsafe-undefined)] returns @racket[unsafe-undefined].
|
|
Thus, a field-initializing assignment---one that is intended to replace the
|
|
@racket[unsafe-undefined] value of a field---should be wrapped with
|
|
@racket[(with-continuation-mark prop:chaperone-unsafe-undefined
|
|
unsafe-undefined ....)].}
|
|
|
|
|
|
@defthing[prop:chaperone-unsafe-undefined struct-type-property?]{
|
|
|
|
A @tech{structure type property} that causes a structure type's
|
|
constructor to produce a @tech{chaperone} of an instance
|
|
in the same way as @racket[chaperone-struct-unsafe-undefined].
|
|
|
|
The property value should be a list of symbols used as field names,
|
|
but the list should be in reverse order of the structure's fields.
|
|
When a field access or assignment would produce or replace
|
|
@racket[unsafe-undefined], the @racket[exn:fail:contract:variable]
|
|
exception is raised if a field name is provided by the structure
|
|
property's value, otherwise the @racket[exn:fail:contract] exception
|
|
is raised.}
|