add racket/undefined
The `(letrec ([x x]) x)` pattern for getting the undefined value will cease to work in a near-future version of Racket (ater v6.0.1). Instead, the initial refernce to `x` will produce a "variable used before its definition" error. For libraries that need an "undefined" value, this new library provides `undefined`, and the library will continue to work in future Racket versions. The library also provides a `check-no-undefined` operation that normally should be wrapped around an expression to keep it from producing `undefined`. For example, the class system initializes object fields with `undefined`, but it could (and will, eventually) wrap each access to a field within `class` to check that the field's value is not `undefined`.
This commit is contained in:
parent
1d8cfea1fc
commit
8abf78256a
|
@ -155,20 +155,44 @@ Sets the content of @racket[box] to @racket[v].}
|
|||
@include-section["procedures.scrbl"]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "void"]{Void and Undefined}
|
||||
@section[#:tag "void"]{Void}
|
||||
|
||||
The constant @|void-const| is returned by most forms and procedures
|
||||
that have a side-effect and no useful result. The constant
|
||||
@|undefined-const| is used as the initial value for @racket[letrec]
|
||||
bindings.
|
||||
that have a side-effect and no useful result.
|
||||
|
||||
The @|void-const| value is always @racket[eq?] to itself, and the
|
||||
@|undefined-const| value is also @racket[eq?] to itself.
|
||||
The @|void-const| value is always @racket[eq?] to itself.
|
||||
|
||||
@defproc[(void? [v any/c]) void?]{Returns @racket[#t] if @racket[v] is the
|
||||
@defproc[(void? [v any/c]) boolean?]{Returns @racket[#t] if @racket[v] is the
|
||||
constant @|void-const|, @racket[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(void [v any/c] ...) void?]{Returns the constant @|void-const|. Each
|
||||
@racket[v] argument is ignored.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "undefined"]{Undefined}
|
||||
|
||||
The constant @|undefined-const| is used as the initial value for
|
||||
@racket[letrec] bindings.
|
||||
|
||||
The @|undefined-const| value is always @racket[eq?] to itself.
|
||||
|
||||
@note-lib[racket/undefined]
|
||||
|
||||
@history[#:added "6.0.0.6"]
|
||||
|
||||
@defproc[(undefined? [v any/c]) boolean?]{Returns @racket[#t] if @racket[v] is the
|
||||
constant @|undefined-const|, @racket[#f] otherwise.}
|
||||
|
||||
|
||||
@defthing[undefined undefined?]{The @|undefined-const| constant.}
|
||||
|
||||
@defproc[(check-not-undefined [v any/c] [sym symbol?]) (and/c any/c (not/c undefined?))]{
|
||||
|
||||
Checks whether @racket[v] is @|undefined-const|, and raises
|
||||
@racket[exn:fail:contract:variable] in that case with an error message
|
||||
along the lines of ``@racket[sym]: variable used before its definition.''
|
||||
If @racket[v] is not @|undefined-const|, then @racket[v] is returned.
|
||||
|
||||
}
|
||||
|
|
21
racket/collects/racket/undefined.rkt
Normal file
21
racket/collects/racket/undefined.rkt
Normal file
|
@ -0,0 +1,21 @@
|
|||
#lang racket/base
|
||||
(require '#%kernel)
|
||||
|
||||
(provide check-not-undefined
|
||||
undefined
|
||||
undefined?)
|
||||
|
||||
;; In a future version of Racket, this `letrec` pattern
|
||||
;; will not work, but the `racket/undefined` library will
|
||||
;; still export an `undefined`:
|
||||
(define undefined (letrec ([x x]) x))
|
||||
|
||||
(define (undefined? v) (eq? v undefined))
|
||||
(define (check-not-undefined v s)
|
||||
(unless (symbol? s) (raise-argument-error 'check-not-undefined "symbol?" 1 v s))
|
||||
(if (eq? v undefined)
|
||||
(raise (make-exn:fail:contract:variable
|
||||
(format "~a: variable used before its definition" s)
|
||||
(current-continuation-marks)
|
||||
s))
|
||||
v))
|
Loading…
Reference in New Issue
Block a user