35 KiB
Built-In Datatypes
The previous chapter introduced some of Racket’s built-in datatypes: numbers, booleans, strings, lists, and procedures. This section provides a more complete coverage of the built-in datatypes for simple forms of data.
1 Booleans
2 Numbers
3 Characters
4 Strings \(Unicode\)
5 Bytes and Byte Strings
6 Symbols
7 Keywords
8 Pairs and Lists
9 Vectors
10 Hash Tables
11 Boxes
12 Void and Undefined
1. Booleans
Racket has two distinguished constants to represent boolean values: #t
for true and #f
for false. Uppercase #T
and #F
are parsed as the
same values, but the lowercase forms are preferred.
The boolean?
procedure recognizes the two boolean constants. In the
result of a test expression for if
, cond
, and
, or
, etc.,
however, any value other than #f
counts as true.
Examples:
> (= 2 (+ 1 1))
#t
> (boolean? #t)
#t
> (boolean? #f)
#t
> (boolean? "no")
#f
> (if "no" 1 0)
1
2. Numbers
A Racket number is either exact or inexact:
-
An exact number is either
-
an arbitrarily large or small integer, such as
5
,99999999999999999
, or-17
; -
a rational that is exactly the ratio of two arbitrarily small or large integers, such as
1/2
,99999999999999999/2
, or-3/4
; or -
a complex number with exact real and imaginary parts (where the imaginary part is not zero), such as
1+2i
or1/2+3/4i
.
-
-
An inexact number is either
-
an IEEE floating-point representation of a number, such as
2.0
or3.14e+87
, where the IEEE infinities and not-a-number are written+inf.0
,-inf.0
, and+nan.0
or `-nan.0`
; or -
a complex number with real and imaginary parts that are IEEE floating-point representations, such as
2.0+3.0i
or-inf.0+nan.0i
; as a special case, an inexact complex number can have an exact zero real part with an inexact imaginary part.
-
Inexact numbers print with a decimal point or exponent specifier, and
exact numbers print as integers and fractions. The same conventions
apply for reading number constants, but #e
or #i
can prefix a number
to force its parsing as an exact or inexact number. The prefixes #b
,
#o
, and #x
specify binary, octal, and hexadecimal interpretation of
digits.
+[missing] in [missing] documents the fine points of the syntax of numbers.
Examples:
> 0.5
0.5
> #e0.5
1/2
> #x03BB
955
Computations that involve an inexact number produce inexact results, so
that inexactness acts as a kind of taint on numbers. Beware, however,
that Racket offers no “inexact booleans,” so computations that branch on
the comparison of inexact numbers can nevertheless produce exact
results. The procedures exact->inexact
and inexact->exact
convert
between the two types of numbers.
Examples:
> (/ 1 2)
1/2
> (/ 1 2.0)
0.5
> (if (= 3.0 2.999) 1 2)
2
> (inexact->exact 0.1)
3602879701896397/36028797018963968
Inexact results are also produced by procedures such as sqrt
, log
,
and sin
when an exact result would require representing real numbers
that are not rational. Racket can represent only rational numbers and
complex numbers with rational parts.
Examples:
> (sin 0) ; rational...
0
> (sin 1/2) ; not rational...
0.479425538604203
In terms of performance, computations with small integers are typically the fastest, where “small” means that the number fits into one bit less than the machine’s word-sized representation for signed numbers. Computation with very large exact integers or with non-integer exact numbers can be much more expensive than computation with inexact numbers.
(define (sigma f a b)
(if (= a b)
0
(+ (f a) (sigma f (+ a 1) b))))
> (time (round (sigma (lambda (x) (/ 1 x)) 1 2000)))
cpu time: 63 real time: 64 gc time: 0
8
> (time (round (sigma (lambda (x) (/ 1.0 x)) 1 2000)))
cpu time: 1 real time: 0 gc time: 0
8.0
The number categories integer, rational, real always rational
,
and complex are defined in the usual way, and are recognized by the
procedures integer?
, rational?
, real?
, and complex?
, in addition
to the generic number?
. A few mathematical procedures accept only real
numbers, but most implement standard extensions to complex numbers.
Examples:
> (integer? 5)
#t
> (complex? 5)
#t
> (integer? 5.0)
#t
> (integer? 1+2i)
#f
> (complex? 1+2i)
#t
> (complex? 1.0+2.0i)
#t
> (abs -5)
5
> (abs -5+2i)
abs: contract violation
expected: real?
given: -5+2i
> (sin -5+2i)
3.6076607742131563+1.0288031496599337i
The =
procedure compares numbers for numerical equality. If it is
given both inexact and exact numbers to compare, it essentially converts
the inexact numbers to exact before comparing. The eqv?
(and
therefore equal?
) procedure, in contrast, compares numbers
considering both exactness and numerical equality.
Examples:
> (= 1 1.0)
#t
> (eqv? 1 1.0)
#f
Beware of comparisons involving inexact numbers, which by their nature
can have surprising behavior. Even apparently simple inexact numbers may
not mean what you think they mean; for example, while a base-2 IEEE
floating-point number can represent 1/2
exactly, it can only
approximate 1/10
:
Examples:
> (= 1/2 0.5)
#t
> (= 1/10 0.1)
#f
> (inexact->exact 0.1)
3602879701896397/36028797018963968
+[missing] in [missing] provides more on numbers and number procedures.
3. Characters
A Racket character corresponds to a Unicode scalar value. Roughly, a scalar value is an unsigned integer whose representation fits into 21 bits, and that maps to some notion of a natural-language character or piece of a character. Technically, a scalar value is a simpler notion than the concept called a “character” in the Unicode standard, but it’s an approximation that works well for many purposes. For example, any accented Roman letter can be represented as a scalar value, as can any common Chinese character.
Although each Racket character corresponds to an integer, the character
datatype is separate from numbers. The char->integer
and
integer->char
procedures convert between scalar-value numbers and the
corresponding character.
A printable character normally prints as #\
followed by the
represented character. An unprintable character normally prints as #\u
followed by the scalar value as hexadecimal number. A few characters are
printed specially; for example, the space and linefeed characters print
as #\space
and #\newline
, respectively.
+[missing] in [missing] documents the fine points of the syntax of characters.
Examples:
> (integer->char 65)
#\A
> (char->integer #\A)
65
> #\λ
#\λ
> #\u03BB
#\λ
> (integer->char 17)
#\u0011
> (char->integer #\space)
32
The display
procedure directly writes a character to the current
output port see \[missing\]
, in contrast to the character-constant
syntax used to print a character result.
Examples:
> #\A
#\A
> (display #\A)
A
Racket provides several classification and conversion procedures on characters. Beware, however, that conversions on some Unicode characters work as a human would expect only when they are in a string (e.g., upcasing “ß” or downcasing “Σ”).
Examples:
> (char-alphabetic? #\A)
#t
> (char-numeric? #\0)
#t
> (char-whitespace? #\newline)
#t
> (char-downcase #\A)
#\a
> (char-upcase #\ß)
#\ß
The char=?
procedure compares two or more characters, and char-ci=?
compares characters ignoring case. The eqv?
and equal?
procedures
behave the same as char=?
on characters; use char=?
when you want to
more specifically declare that the values being compared are characters.
Examples:
> (char=? #\a #\A)
#f
> (char-ci=? #\a #\A)
#t
> (eqv? #\a #\A)
#f
+[missing] in [missing] provides more on characters and character procedures.
4. Strings Unicode
A string is a fixed-length array of characters. It prints using
doublequotes, where doublequote and backslash characters within the
string are escaped with backslashes. Other common string escapes are
supported, including \n
for a linefeed, \r
for a carriage return,
octal escapes using \
followed by up to three octal digits, and
hexadecimal escapes with \u
up to four digits
. Unprintable
characters in a string are normally shown with \u
when the string is
printed.
+[missing] in [missing] documents the fine points of the syntax of strings.
The display
procedure directly writes the characters of a string to
the current output port see \[missing\]
, in contrast to the
string-constant syntax used to print a string result.
Examples:
> "Apple"
"Apple"
> "\u03BB"
"λ"
> (display "Apple")
Apple
> (display "a \"quoted\" thing")
a "quoted" thing
> (display "two\nlines")
two
lines
> (display "\u03BB")
λ
A string can be mutable or immutable; strings written directly as
expressions are immutable, but most other strings are mutable. The
make-string
procedure creates a mutable string given a length and
optional fill character. The string-ref
procedure accesses a character
from a string with 0-based indexing
; the string-set!
procedure
changes a character in a mutable string.
Examples:
> (string-ref "Apple" 0)
#\A
> (define s (make-string 5 #\.))
> s
"....."
> (string-set! s 2 #\λ)
> s
"..λ.."
String ordering and case operations are generally locale-independent;
that is, they work the same for all users. A few locale-dependent
operations are provided that allow the way that strings are case-folded
and sorted to depend on the end-user’s locale. If you’re sorting
strings, for example, use string<?
or string-ci<?
if the sort result
should be consistent across machines and users, but use
string-locale<?
or string-locale-ci<?
if the sort is purely to order
strings for an end user.
Examples:
> (string<? "apple" "Banana")
#f
> (string-ci<? "apple" "Banana")
#t
> (string-upcase "Straße")
"STRASSE"
> (parameterize ([current-locale "C"])
(string-locale-upcase "Straße"))
"STRAßE"
For working with plain ASCII, working with raw bytes, or encoding/decoding Unicode strings as bytes, use byte strings.
+[missing] in [missing] provides more on strings and string procedures.
5. Bytes and Byte Strings
A byte is an exact integer between 0
and 255
, inclusive. The
byte?
predicate recognizes numbers that represent bytes.
Examples:
> (byte? 0)
#t
> (byte? 256)
#f
A byte string is similar to a string—see Strings Unicode
—but its
content is a sequence of bytes instead of characters. Byte strings can
be used in applications that process pure ASCII instead of Unicode text.
The printed form of a byte string supports such uses in particular,
because a byte string prints like the ASCII decoding of the byte string,
but prefixed with a #
. Unprintable ASCII characters or non-ASCII bytes
in the byte string are written with octal notation.
+[missing] in [missing] documents the fine points of the syntax of byte strings.
Examples:
> #"Apple"
#"Apple"
> (bytes-ref #"Apple" 0)
65
> (make-bytes 3 65)
#"AAA"
> (define b (make-bytes 2 0))
> b
#"\0\0"
> (bytes-set! b 0 1)
> (bytes-set! b 1 255)
> b
#"\1\377"
The display
form of a byte string writes its raw bytes to the current
output port see \[missing\]
. Technically, display
of a normal
i.e,. character
string prints the UTF-8 encoding of the string to
the current output port, since output is ultimately defined in terms of
bytes; display
of a byte string, however, writes the raw bytes with no
encoding. Along the same lines, when this documentation shows output, it
technically shows the UTF-8-decoded form of the output.
Examples:
> (display #"Apple")
Apple
> (display "\316\273") ; same as "λ"
λ
> (display #"\316\273") ; UTF-8 encoding of λ
λ
For explicitly converting between strings and byte strings, Racket
supports three kinds of encodings directly: UTF-8, Latin-1, and the
current locale’s encoding. General facilities for byte-to-byte
conversions especially to and from UTF-8
fill the gap to support
arbitrary string encodings.
Examples:
> (bytes->string/utf-8 #"\316\273")
"λ"
> (bytes->string/latin-1 #"\316\273")
"λ"
> (parameterize ([current-locale "C"]) ; C locale supports ASCII,
(bytes->string/locale #"\316\273")) ; only, so...
bytes->string/locale: byte string is not a valid encoding
for the current locale
byte string: #"\316\273"
> (let ([cvt (bytes-open-converter "cp1253" ; Greek code page
"UTF-8")]
[dest (make-bytes 2)])
(bytes-convert cvt #"\353" 0 1 dest)
(bytes-close-converter cvt)
(bytes->string/utf-8 dest))
"λ"
+[missing] in [missing] provides more on byte strings and byte-string procedures.
6. Symbols
A symbol is an atomic value that prints like an identifier preceded
with '
. An expression that starts with '
and continues with an
identifier produces a symbol value.
Examples:
> 'a
'a
> (symbol? 'a)
#t
For any sequence of characters, exactly one corresponding symbol is
interned; calling the string->symbol
procedure, or read
ing a
syntactic identifier, produces an interned symbol. Since interned
symbols can be cheaply compared with eq?
(and thus eqv?
or
equal?
), they serve as a convenient values to use for tags and
enumerations.
Symbols are case-sensitive. By using a #ci
prefix or in other ways,
the reader can be made to case-fold character sequences to arrive at a
symbol, but the reader preserves case by default.
Examples:
> (eq? 'a 'a)
#t
> (eq? 'a (string->symbol "a"))
#t
> (eq? 'a 'b)
#f
> (eq? 'a 'A)
#f
> #ci'A
'a
Any string i.e., any character sequence
can be supplied to
string->symbol
to obtain the corresponding symbol. For reader input,
any character can appear directly in an identifier, except for
whitespace and the following special characters:
(
)
[
]
{
}
"
,
'
;
#
|
`
Actually, #
is disallowed only at the beginning of a symbol, and then
only if not followed by %
; otherwise, #
is allowed, too. Also, .
by itself is not a symbol.
Whitespace or special characters can be included in an identifier by
quoting them with |
or \
. These quoting mechanisms are used in the
printed form of identifiers that contain special characters or that
might otherwise look like numbers.
Examples:
> (string->symbol "one, two")
'|one, two|
> (string->symbol "6")
'|6|
+[missing] in [missing] documents the fine points of the syntax of symbols.
The write
function prints a symbol without a '
prefix. The display
form of a symbol is the same as the corresponding string.
Examples:
> (write 'Apple)
Apple
> (display 'Apple)
Apple
> (write '|6|)
|6|
> (display '|6|)
6
The gensym
and string->uninterned-symbol
procedures generate fresh
uninterned symbols that are not equal according to `eq?`
to any
previously interned or uninterned symbol. Uninterned symbols are useful
as fresh tags that cannot be confused with any other value.
Examples:
> (define s (gensym))
> s
'g42
> (eq? s 'g42)
#f
> (eq? 'a (string->uninterned-symbol "a"))
#f
+[missing] in [missing] provides more on symbols.
7. Keywords
A keyword value is similar to a symbol see Symbols
, but its
printed form is prefixed with #:
.
+[missing] in [missing] documents the fine points of the syntax of keywords.
Examples:
> (string->keyword "apple")
'#:apple
> '#:apple
'#:apple
> (eq? '#:apple (string->keyword "apple"))
#t
More precisely, a keyword is analogous to an identifier; in the same way
that an identifier can be quoted to produce a symbol, a keyword can be
quoted to produce a value. The same term “keyword” is used in both
cases, but we sometimes use keyword value to refer more specifically
to the result of a quote-keyword expression or of string->keyword
. An
unquoted keyword is not an expression, just as an unquoted identifier
does not produce a symbol:
Examples:
> not-a-symbol-expression
not-a-symbol-expression: undefined;
cannot reference an identifier before its definition
in module: top-level
> #:not-a-keyword-expression
eval:2:0: #%datum: keyword misused as an expression
at: #:not-a-keyword-expression
Despite their similarities, keywords are used in a different way than
identifiers or symbols. Keywords are intended for use unquoted
as
special markers in argument lists and in certain syntactic forms. For
run-time flags and enumerations, use symbols instead of keywords. The
example below illustrates the distinct roles of keywords and symbols.
Examples:
> (define dir (find-system-path 'temp-dir)) ; not '#:temp-dir
> (with-output-to-file (build-path dir "stuff.txt")
(lambda () (printf "example\n"))
; optional #:mode argument can be 'text or 'binary
#:mode 'text
; optional #:exists argument can be 'replace, 'truncate, ...
#:exists 'replace)
8. Pairs and Lists
A pair joins two arbitrary values. The cons
procedure constructs
pairs, and the car
and cdr
procedures extract the first and second
elements of the pair, respectively. The pair?
predicate recognizes
pairs.
Some pairs print by wrapping parentheses around the printed forms of the
two pair elements, putting a '
at the beginning and a .
between the
elements.
Examples:
> (cons 1 2)
'(1 . 2)
> (cons (cons 1 2) 3)
'((1 . 2) . 3)
> (car (cons 1 2))
1
> (cdr (cons 1 2))
2
> (pair? (cons 1 2))
#t
A list is a combination of pairs that creates a linked list. More
precisely, a list is either the empty list null
, or it is a pair whose
first element is a list element and whose second element is a list. The
list?
predicate recognizes lists. The null?
predicate recognizes
the empty list.
A list normally prints as a '
followed by a pair of parentheses
wrapped around the list elements.
Examples:
> null
'()
> (cons 0 (cons 1 (cons 2 null)))
'(0 1 2)
> (list? null)
#t
> (list? (cons 1 (cons 2 null)))
#t
> (list? (cons 1 2))
#f
A list or pair prints using list
or cons
when one of its elements
cannot be written as a quote
d value. For example, a value constructed
with srcloc
cannot be written using quote
, and it prints using
srcloc
:
> (srcloc "file.rkt" 1 0 1 (+ 4 4))
(srcloc "file.rkt" 1 0 1 8)
> (list 'here (srcloc "file.rkt" 1 0 1 8) 'there)
(list 'here (srcloc "file.rkt" 1 0 1 8) 'there)
> (cons 1 (srcloc "file.rkt" 1 0 1 8))
(cons 1 (srcloc "file.rkt" 1 0 1 8))
> (cons 1 (cons 2 (srcloc "file.rkt" 1 0 1 8)))
(list* 1 2 (srcloc "file.rkt" 1 0 1 8))
See also
list*
.
As shown in the last example, list*
is used to abbreviate a series of
cons
es that cannot be abbreviated using list
.
The write
and display
functions print a pair or list without a
leading '
, cons
, list
, or list*
. There is no difference between
write
and display
for a pair or list, except as they apply to
elements of the list:
Examples:
> (write (cons 1 2))
(1 . 2)
> (display (cons 1 2))
(1 . 2)
> (write null)
()
> (display null)
()
> (write (list 1 2 "3"))
(1 2 "3")
> (display (list 1 2 "3"))
(1 2 3)
Among the most important predefined procedures on lists are those that iterate through the list’s elements:
> (map (lambda (i) (/ 1 i))
'(1 2 3))
'(1 1/2 1/3)
> (andmap (lambda (i) (i . < . 3))
'(1 2 3))
#f
> (ormap (lambda (i) (i . < . 3))
'(1 2 3))
#t
> (filter (lambda (i) (i . < . 3))
'(1 2 3))
'(1 2)
> (foldl (lambda (v i) (+ v i))
10
'(1 2 3))
16
> (for-each (lambda (i) (display i))
'(1 2 3))
123
> (member "Keys"
'("Florida" "Keys" "U.S.A."))
'("Keys" "U.S.A.")
> (assoc 'where
'((when "3:30") (where "Florida") (who "Mickey")))
'(where "Florida")
+[missing] in [missing] provides more on pairs and lists.
Pairs are immutable contrary to Lisp tradition
, and pair?
and
list?
recognize immutable pairs and lists, only. The mcons
procedure
creates a mutable pair, which works with set-mcar!
and set-mcdr!
,
as well as mcar
and mcdr
. A mutable pair prints using mcons
, while
write
and display
print mutable pairs with {
and }
:
Examples:
> (define p (mcons 1 2))
> p
(mcons 1 2)
> (pair? p)
#f
> (mpair? p)
#t
> (set-mcar! p 0)
> p
(mcons 0 2)
> (write p)
{0 . 2}
+[missing] in [missing] provides more on mutable pairs.
9. Vectors
A vector is a fixed-length array of arbitrary values. Unlike a list, a vector supports constant-time access and update of its elements.
A vector prints similar to a list—as a parenthesized sequence of its
elements—but a vector is prefixed with #
after '
, or it uses
vector
if one of its elements cannot be expressed with quote
.
For a vector as an expression, an optional length can be supplied. Also,
a vector as an expression implicitly quote
s the forms for its content,
which means that identifiers and parenthesized forms in a vector
constant represent symbols and lists.
+[missing] in [missing] documents the fine points of the syntax of vectors.
Examples:
> #("a" "b" "c")
'#("a" "b" "c")
> #(name (that tune))
'#(name (that tune))
> #4(baldwin bruce)
'#(baldwin bruce bruce bruce)
> (vector-ref #("a" "b" "c") 1)
"b"
> (vector-ref #(name (that tune)) 1)
'(that tune)
Like strings, a vector is either mutable or immutable, and vectors written directly as expressions are immutable.
Vectors can be converted to lists and vice versa via vector->list
and
list->vector
; such conversions are particularly useful in combination
with predefined procedures on lists. When allocating extra lists seems
too expensive, consider using looping forms like for/fold
, which
recognize vectors as well as lists.
Example:
> (list->vector (map string-titlecase
(vector->list #("three" "blind" "mice"))))
'#("Three" "Blind" "Mice")
+[missing] in [missing] provides more on vectors and vector procedures.
10. Hash Tables
A hash table implements a mapping from keys to values, where both keys
and values can be arbitrary Racket values, and access and update to the
table are normally constant-time operations. Keys are compared using
equal?
, eqv?
, or eq?
, depending on whether the hash table is
created with make-hash
, make-hasheqv
, or make-hasheq
.
Examples:
> (define ht (make-hash))
> (hash-set! ht "apple" '(red round))
> (hash-set! ht "banana" '(yellow long))
> (hash-ref ht "apple")
'(red round)
> (hash-ref ht "coconut")
hash-ref: no value found for key
key: "coconut"
> (hash-ref ht "coconut" "not there")
"not there"
The hash
, hasheqv
, and hasheq
functions create immutable hash
tables from an initial set of keys and values, in which each value is
provided as an argument after its key. Immutable hash tables can be
extended with hash-set
, which produces a new immutable hash table in
constant time.
Examples:
> (define ht (hash "apple" 'red "banana" 'yellow))
> (hash-ref ht "apple")
'red
> (define ht2 (hash-set ht "coconut" 'brown))
> (hash-ref ht "coconut")
hash-ref: no value found for key
key: "coconut"
> (hash-ref ht2 "coconut")
'brown
A literal immutable hash table can be written as an expression by using
#hash
for an `equal?`-based table
, #hasheqv
(for an
eqv?
-based table), or #hasheq
for an `eq?`-based table
. A
parenthesized sequence must immediately follow #hash
, #hasheq
, or
#hasheqv
, where each element is a dotted key–value pair. The #hash
,
etc. forms implicitly quote
their key and value sub-forms.
Examples:
> (define ht #hash(("apple" . red)
("banana" . yellow)))
> (hash-ref ht "apple")
'red
+[missing] in [missing] documents the fine points of the syntax of hash table literals.
Both mutable and immutable hash tables print like immutable hash tables,
using a quoted #hash
, #hasheqv
, or #hasheq
form if all keys and
values can be expressed with quote
or using hash
, hasheq
, or
hasheqv
otherwise:
Examples:
> #hash(("apple" . red)
("banana" . yellow))
'#hash(("banana" . yellow) ("apple" . red))
> (hash 1 (srcloc "file.rkt" 1 0 1 (+ 4 4)))
(hash 1 (srcloc "file.rkt" 1 0 1 8))
A mutable hash table can optionally retain its keys weakly, so each mapping is retained only so long as the key is retained elsewhere.
Examples:
> (define ht (make-weak-hasheq))
> (hash-set! ht (gensym) "can you see me?")
> (collect-garbage)
> (hash-count ht)
0
Beware that even a weak hash table retains its values strongly, as long as the corresponding key is accessible. This creates a catch-22 dependency when a value refers back to its key, so that the mapping is retained permanently. To break the cycle, map the key to an ephemeron that pairs the value with its key (in addition to the implicit pairing of the hash table).
+[missing] in [missing] documents the fine points of using ephemerons.
Examples:
> (define ht (make-weak-hasheq))
> (let ([g (gensym)])
(hash-set! ht g (list g)))
> (collect-garbage)
> (hash-count ht)
1
> (define ht (make-weak-hasheq))
> (let ([g (gensym)])
(hash-set! ht g (make-ephemeron g (list g))))
> (collect-garbage)
> (hash-count ht)
0
+[missing] in [missing] provides more on hash tables and hash-table procedures.
11. Boxes
A box is like a single-element vector. It can print as a quoted #&
followed by the printed form of the boxed value. A #&
form can also be
used as an expression, but since the resulting box is constant, it has
practically no use.
Examples:
> (define b (box "apple"))
> b
'#&"apple"
> (unbox b)
"apple"
> (set-box! b '(banana boat))
> b
'#&(banana boat)
+[missing] in [missing] provides more on boxes and box procedures.
12. Void and Undefined
Some procedures or expression forms have no need for a result value. For
example, the display
procedure is called only for the side-effect of
writing output. In such cases the result value is normally a special
constant that prints as #<void>
. When the result of an expression is
simply #<void>
, the REPL does not print anything.
The void
procedure takes any number of arguments and returns
#<void>
. (That is, the identifier void
is bound to a procedure that
returns #<void>
, instead of being bound directly to #<void>
.)
Examples:
> (void)
> (void 1 2 3)
> (list (void))
'(#<void>)
The undefined
constant, which prints as #<undefined>
, is sometimes
used as the result of a reference whose value is not yet available. In
previous versions of Racket before version 6.1
, referencing a local
binding too early produced #<undefined>
; too-early references now
raise an exception, instead.
The
undefined
result can still be produced in some cases by theshared
form.
(define (fails)
(define x x)
x)
> (fails)
x: undefined;
cannot use before initialization