racket/pkgs/racket-doc/scribblings/reference/unsafe-undefined.scrbl

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