Basic Data Extensions

MzScheme returns the unique **void** value -- printed as
`#<void>`

-- for expressions that have unspecified results in
*R5RS*. The procedure

takes any
number of arguments and returns void:
`void`

Variables bound by `letrec-values`

that are accessible but
not yet initialized are bound to the unique **undefined**
value, printed as `#<undefined>`

.

Unless otherwise specified, two instances of a particular MzScheme
data type are

only when they are `equal?`

. Two
values are `eq?`

only when they are either `eqv?`

,
`eq?`

`=`

and have the same exactness, or both `+nan.0`

.

The

and `andmap`

procedures apply a test
procedure to the elements of a list, returning immediately when the
result for testing the entire list is determined. The arguments to
`ormap`

and `andmap`

are the same as for `ormap`

, but a
single boolean value is returned as the result, rather than a list:
`map`

`(andmap`

`proc list`

`···`^{1}`)`

applies`proc`

to elements of the`list`

s from the first elements to the last, returning`#f`

as soon as any application returns`#f`

. If no application of`proc`

returns`#f`

, then the result of the last application of`proc`

is returned. If the`list`

s are empty, then`#t`

is returned.`(ormap`

`proc list`

`···`^{1}`)`

applies`proc`

to elements of the`list`

s from the first elements to the last. If any application returns a value other than`#f`

, that value is immediately returned as the result of the

application. If all applications of`ormap`

`proc`

return`#f`

, then the result is`#f`

. If the`list`

s are empty, then`#f`

is returned.

Examples:

(`andmap`

`positive?`

'(1 2 3)) ; =>`#t`

(`ormap`

`eq?`

'(a b c) '(a b c)) ; =>`#t`

(`andmap`

`positive?`

'(1 2 a)) ; => raises`(`

`exn:application:type`

`ormap`

`positive?`

'(1 2 a)) ; =>`#t`

(`andmap`

`positive?`

'(1 -2 a)) ; =>`#f`

(`andmap`

+ '(1 2 3) '(4 5 6)) ; =>`9`

(`ormap`

+ '(1 2 3) '(4 5 6)) ; =>`5`

A number in MzScheme is one of the following:

a

**fixnum**exact integer (30 bits^{2}plus a sign bit)a

**bignum**exact integer (cannot be represented in a fixnum)a

**fraction**exact rational (represented by two exact integers)a

**flonum**inexact rational (double-precision floating-point number)a

**complex**number; either the real and imaginary parts are both exact or inexact, or the number has an exact zero real part and an inexact imaginary part; a complex number with an inexact zero imaginary part is a real number

MzScheme extends the number syntax of *R5RS* in two ways:

All input radixes (

`#b`

,`#o`

,`#d`

, and`#x`

) allow ``decimal'' numbers that contain a period or exponent marker. For example,`#b1.1`

is equivalent to`1.5`

. In hexadecimal numbers,

and`e`

`d`

always stand for a hexadecimal digit, not an exponent marker.The following are inexact numerical constants:

`+inf.0`

(infinity),`-inf.0`

(negative infinity),`+nan.0`

(not a number), and`-nan.0`

(same as`+nan.0`

). These names can also be used within complex constants, as in`-inf.0+inf.0i`

.

The special inexact numbers `+inf.0`

, `-inf.0`

, and
`+nan.0`

have no exact form. Dividing by an inexact zero returns
`+inf.0`

or `-inf.0`

, depending on the sign of the
dividend. The infinities are integers, and they answer `#t`

for
both `even?`

and `odd?`

. The `+nan.0`

value is not an
integer and is not `=`

to itself, but `+nan.0`

is
`eqv?`

to itself.^{3} Similarly, `(= 0.0 -0.0)`

is `#t`

, but `(`

is `eqv?`

0.0 -0.0)`#f`

.

All multi-argument arithmetic procedures operate pairwise on arguments from left to right.

The `string->number`

procedure works on all number
representations and exact integer radix values in the range `2`

to `16`

(inclusive). The `number->string`

procedure
accepts all number types and the radix values `2`

, `8`

,
`10`

, and `16`

; however, if an inexact number is provided
with a radix other than `10`

, the
`exn:application:mismatch`

exception is raised.

The

and `add1`

procedures work on any number:
`sub1`

The following procedures work on integers:

`(quotient/remainder`

`n1 n2`

`)`

returns two values:`(`

and`quotient`

n1 n2)`(`

.`remainder`

n1 n2)`(integer-sqrt`

`n`

`)`

returns the integer square-root of`n`

. For positive`n`

, the result is the largest positive integer bounded by the`(`

. For negative`sqrt`

n)`n`

, the result is`(* (`

.`integer-sqrt`

(- n)) 0+i)`(integer-sqrt/remainder`

`n`

`)`

returns two values:`(`

and`integer-sqrt`

n)`(- n (`

.`expt`

(`integer-sqrt`

n) 2))

The following procedures work on exact integers in their (semi-infinite) two's complement representation:

`(bitwise-ior`

`n`

`···`^{1}`)`

returns the bitwise ``inclusive or'' of the`n`

s.`(bitwise-and`

`n`

`···`^{1}`)`

returns the bitwise ``and'' of the`n`

s.`(bitwise-xor`

`n`

`···`^{1}`)`

returns the bitwise ``exclusive or'' of the`n`

s.`(bitwise-not`

`n`

`)`

returns the bitwise ``not'' of`n`

.`(arithmetic-shift`

`n m`

`)`

returns the bitwise ``shift'' of`n`

. The integer`n`

is shifted left by`m`

bits; i.e.,`m`

new zeros are introduced as rightmost digits. If`m`

is negative,`n`

is shifted right by`-``m`

bits; i.e., the rightmost`m`

digits are dropped.

The

procedure generates pseudo-random integers:
`random`

`(random`

`k`

`)`

returns a random exact integer in the range`0`

to`k`

`-`1 where`k`

is an exact integer between 1 and 2^{31}`-`1, inclusive. The number is provided by the current pseudo-random number generator, which maintains an internal state for generating numbers.^{4}`(random-seed`

`k`

`)`

seeds the current pseudo-random number generator with`k`

, an exact integer between 0 and 2^{31}`-`1, inclusive. Seeding a generator sets its internal state deterministically; seeding a generator with a particular number forces it to produce a sequence of pseudo-random numbers that is the same across runs and across platforms.`(current-pseudo-random-generator`

`)`

returns the current pseudo-random number generator, and`(current-pseudo-random-generator`

`generator`

`)`

sets the current generator to`generator`

. See also section 7.7.1.10.`(make-pseudo-random-generator`

`)`

returns a new pseudo-random number generator. The new generator is seeded with a number derived from`(`

.`current-milliseconds`

)`(pseudo-random-generator?`

`v`

`)`

returns`#t`

if`v`

is a pseudo-random number generator,`#f`

otherwise.

The following procedures convert between Scheme numbers and common machine byte representations:

`(integer-byte-string->integer`

`string signed?`

`big-endian?`

]`)`

converts the machine-format number encoded in`string`

to an exact integer. The`string`

must contain either 2, 4, or 8 characters. If`signed?`

is true, then the string is decoded as a two's-complement number, otherwise it is decoded as an unsigned integer. If`big-endian?`

is true, then the first character's ASCII value provides the most significant eight bits of the number, otherwise the first character provides the least-significant eight bits, and so on. The default value of`big-endian?`

is the result of

.`system-big-endian?`

`(integer->integer-byte-string`

`n size-n signed?`

`big-endian? to-string`

]`)`

converts the exact integer`n`

to a machine-format number encoded in a string of length`size-n`

, which must be 2, 4, or 8. If`signed?`

is true, then the number is encoded with two's complement, otherwise it is encoded as an unsigned bit stream. If`big-endian?`

is true, then the most significant eight bits of the number are encoded in the first character of the resulting string, otherwise the least-significant bits are encoded in the first character, and so on. The default value of`big-endian?`

is the result of

.`system-big-endian?`

If

`to-string`

is provided, it must be a mutable string of length`size-n`

; in that case, the encoding of`n`

is written into`to-string`

, and`to-string`

is returned as the result. If`to-string`

is not provided, the result is a newly allocated string.If

`n`

cannot be encoded in a string of the requested size and format, the`exn:misc:application`

exception is raised. If`to-string`

is provided and it is not of length`size-n`

, the`exn:misc:application`

exception is raised.`(floating-point-byte-string->real`

`string`

`big-endian?`

]`)`

converts the IEEE floating-point number encoded in`string`

to an inexact real number. The`string`

must contain either 4 or 8 characters. If`big-endian?`

is true, then the first character's ASCII value provides the most significant eight bits of the IEEE representation, otherwise the first character provides the least-significant eight bits, and so on. The default value of`big-endian?`

is the result of

.`system-big-endian?`

`(real->floating-point-byte-string`

`x size-n`

`big-endian? to-string`

]`)`

converts the real number`x`

to its IEEE representation in a string of length`size-n`

, which must be 4 or 8. If`big-endian?`

is true, then the most significant eight bits of the number are encoded in the first character of the resulting string, otherwise the least-significant bits are encoded in the first character, and so on. The default value of`big-endian?`

is the result of

.`system-big-endian?`

If

`to-string`

is provided, it must be a mutable string of length`size-n`

; in that case, the encoding of`n`

is written into`to-string`

, and`to-string`

is returned as the result. If`to-string`

is not provided, the result is a newly allocated string.If

`to-string`

is provided and it is not of length`size-n`

, the`exn:misc:application`

exception is raised.`(system-big-endian?`

`)`

returns`#t`

if the native encoding of numbers is big-endian for the machine running MzScheme,`#f`

if the native encoding is little-endian.

MzScheme character values range over the characters for ``extended
ASCII'' values 0 to 255 (where the ASCII extensions are
platform-specific). The procedure `char->integer`

returns
the extended ASCII value of a character and `integer->char`

takes an extended ASCII value and returns the corresponding
character. If `integer->char`

is given an integer that is
not in 0 to 255 inclusive, the `exn:application:type`

exception is raised.

The procedures

and
`char->latin-1-integer`

support conversions between characters in
the platform-specific character set and platform-independent Latin-1
(ISO 8859-1) values:
`latin-1-integer->char`

`(char->latin-1-integer`

`char`

`)`

returns the integer in 0 to 255 inclusive corresponding to the Latin-1 value for`char`

, or`#f`

if`char`

(in the platform-specific character set) has no corresponding character in Latin-1.`(latin-1-integer->char`

`k`

`)`

returns the character corresponding to the Latin-1 mapping of`k`

, or`#f`

if the platform-specific character set does not support the corresponding Latin-1 character. If`k`

is not in 0 to 255 inclusive, the`exn:application:type`

exception is raised.

For Unix and Mac OS,

and
`char->latin-1-integer`

are the same as `latin-1-integer->char`

and `char->integer`

. For Windows, the platform-specific set
and Latin-1 match except for the range `integer->char`

`#x80`

to `#x9F`

(which are unprintable control characters in Latin-1).

The character comparison procedures -- `char=?`

,
`char<?`

, `char-ci=?`

, etc. -- take two or more
character arguments and check the arguments pairwise (like the
numerical comparison procedures). Two characters are `eq?`

whenever they are `char=?`

. The expression `(`

produces the same result as `char<?`

char1
char2)`(< (`

, etc. The procedures
`char->integer`

char1)
(`char->integer`

char2))`char-whitespace?`

, `char-alphabetic?`

,
`char-numeric?`

, `char-upper-case?`

, and

, `char-upper-case?`

`char-upcase`

, and
`char-downcase`

are fully portable; their results do not
depend on the platform or locales.

In addition to the standard character procedures, MzScheme provides the following locale-sensitive procedures (see section 7.7.1.11):

For example, since ASCII character 112 is a lowercase ``p'' and
Latin-1 character 246 is a lowercase ``ddot*o*'' (with an umlaut),
`(`

tends to produce `char-locale<?`

(`integer->char`

112) (`integer->char`

246))`#f`

, though it always produces `#t`

if the current locale is disabled.

A string can be mutable or immutable. When an immutable string is
provided to a procedure like

, the
`string-set!`

`exn:application:type`

exception is raised.

String constants generated by

are
immutable. `read`

`(string->immutable-string`

` ``string`

`)`

returns an immutable
string with the same content as `string`

, and it returns
`string`

itself if `string`

is immutable. (See also

in section 3.8.)`immutable?`

`(substring`

` ``string start-k`

` `[`end-k`

]`)`

returns a mutable string, even
if the `string`

argument is immutable. The `end-k`

argument
defaults to `(string-length `

`string`

)

`(string-copy!`

` ``dest-string dest-start-k src-string`

` `[`src-start-k src-end-k`

]`)`

changes the characters of `dest-string`

from positions
`dest-start-k`

(inclusive) to `dest-end-k`

(exclsuive) to
match the characters in `src-string`

from `src-start-k`

(inclsuive). If `src-start-k`

is not provided, it defaults to
`0`

. If `src-end-k`

is not provided, it defaults to
`(`

. The strings `string-length`

src-string)`dest-string`

and `src-string`

can be the same string, and in that case the
destination region can overlap with the source region; the
destination characters after the copy match the source characters
from before the copy. If any of `dest-start-k`

,
`src-start-k`

, or `src-end-k`

are out of range (taking into
acount the sizes of the strings and the source and destination
regions), the `exn:fail:contract`

exception is raised.

When a string is created with `make-string`

without a fill
value, it is initialized with the null character (`#\nul`

) in
all positions.

The string comparison procedures -- `string=?`

,
`string<?`

, `string-ci=?`

, etc. -- take two or more
string arguments and check the arguments pairwise (like the numerical
comparison procedures). String comparisons using the standard
functions are fully portable; the results do not depend on the
platform or locales.

In addition to the string character procedures, MzScheme provides the following locale-sensitive procedures (see section 7.7.1.11):

For information about symbol parsing and printing, see section 14.3 and section 14.4, respectively.

MzScheme provides two ways of generating an **uninterned
symbol**, i.e., a symbol that is not

, `eq?`

, or
`eqv?`

to any other symbol, although it may print the same
as another symbol:
`equal?`

`(string->uninterned-symbol`

`string`

`)`

is like`(`

, but the resulting symbol is a new uninterned symbol. Calling`string->symbol`

`string`

)

twice with the same`string->uninterned-symbol`

`string`

returns two distinct symbols.`(gensym`

`symbol/string`

]`)`

creates an uninterned symbol with an automatically-generated name. The optional`symbol/string`

argument is a prefix symbol or string.

Regular (interned) symbols are only weakly held by the internal symbol
table. This weakness can never affect the result of a

,
`eq?`

, or `eqv?`

test, but a symbol placed into a weak box
(see section 13.1) or used as the key in a weak hash table (see
section 3.12) may disappear.`equal?`

When a vector is created with

without a fill
value, it is initialized with `make-vector`

`0`

in all positions. A vector
can be immutable, such as a vector returned by `syntax-e`

, but
vectors generated by `read`

are mutable. (See also

in section 3.8.)`immutable?`

`(vector->immutable-vector`

` ``vec`

`)`

returns an immutable vector with
the same content as `vec`

, and it returns `vec`

itself if
`vec`

is immutable. (See also

in
section 3.8.)`immutable?`

`(vector-immutable`

` ``v`

` ``···`^{1}`)`

is like `(vector v `

except that
the resulting vector is immutable. (See also `···`^{1})

in
section 3.8.)`immutable?`

A cons cell can be mutable or immutable. When an immutable cons cell
is provided to a procedure like

, the
`set-cdr!`

`exn:application:type`

exception is raised. Cons cells generated by

are always mutable.`read`

The global variable `null`

is bound to the empty list.

`(reverse!`

` ``list`

`)`

is the same as `(reverse `

, but
`list`

)`list`

is destructively reversed using

(i.e.,
each cons cell in `set-cdr!`

`list`

is mutated).

`(append!`

` ``list`

` ``···`^{1}`)`

is like
`(append `

, but it destructively appends the
`list`

)`list`

s (i.e., except for the last `list`

, the last cons cell
of each `list`

is mutated to append the lists; empty lists are
essentially dropped).

`(list*`

` ``v`

` ``···`^{1}`)`

is similar to `(`

but the last argument is used directly as the `list`

`v`

`···`^{1})

of the last
pair constructed for the list:
`cdr`

(`list*`

1 2 3 4) ; =>`'(1 2 3 . 4)`

`(cons-immutable`

` ``v1 v2`

`)`

returns an immutable pair whose

is `car`

`v1`

and

is `cdr`

`v2`

.

`(list-immutable`

` ``v`

` ``···`^{1}`)`

is like `(`

, but using
immutable pairs.`list`

v `···`^{1})

`(list*-immutable`

` ``v`

` ``···`^{1}`)`

is like `(`

, but using
immutable pairs.`list*`

v `···`^{1})

`(immutable?`

` ``v`

`)`

returns `#t`

if `v`

is an immutable
cons cell, string, vector, box, or hash table, `#f`

otherwise.

The `list-ref`

and `list-tail`

procedures accept an
improper list as a first argument. If either procedure is applied to
an improper list and an index that would require taking the

or `car`

of a non-cons-cell, the
`cdr`

`exn:application:mismatch`

exception is raised.

The `member`

, `memv`

, and `memq`

procedures
accept an improper list as a second argument. If the membership
search reaches the improper tail, the
`exn:application:mismatch`

exception is raised.

The `assoc`

, `assv`

, and `assq`

procedures
accept an improperly formed association list as a second argument.
If the association search reaches an improper list tail or a list
element that is not a pair, the `exn:application:mismatch`

exception is raised.

MzScheme provides **boxes**, which are records that have a
single field:

`(box`

`v`

`)`

returns a new mutable box that contains`v`

.`(box-immutable`

`v`

`)`

returns a new immutable box that contains`v`

.`(unbox`

`box`

`)`

returns the content of`box`

. For any`v`

,`(unbox (box`

returns`v`

))`v`

.`(set-box!`

`mutable-box v`

`)`

sets the content of`mutable-box`

to`v`

.`(box?`

`v`

`)`

returns`#t`

if`v`

is a box,`#f`

otherwise.

Two boxes are `equal?`

if the contents of the boxes are

.`equal?`

A box returned by

(see section 12.2.2) is
immutable; if `syntax-e`

is applied to such a box, the
`set-box!`

`exn:application:type`

exception is raised. A box produced by `read`

(via
`#&`

) is mutable. (See also

in
section 3.8.)`immutable?`

See section 4.6 for information on defining new procedure types.

MzScheme's

procedure returns the input arity
of a procedure:
`procedure-arity`

`(procedure-arity`

`proc`

`)`

returns information about the number of arguments accepted by the procedure`proc`

. The result`a`

is either:an exact non-negative integer ==> the procedure always takes exactly

`a`

arguments;an

`arity-at-least`

^{5}instance ==> the procedure takes`(`

or more arguments; or`arity-at-least-value`

a)a list containing integers and

`arity-at-least`

instances ==> the procedure takes any number of arguments that can match one of the arities in the list.

`(procedure-arity-includes?`

`proc k`

`)`

returns`#t`

if the procedure can accept`n`

arguments (where`k`

is an exact, non-negative integer),`#f`

otherwise.

Examples:

(`procedure-arity`

`cons`

) ; =>`2`

(`procedure-arity`

`list`

) ; =>`#<struct:arity-at-least>`

(`arity-at-least?`

(`procedure-arity`

`list`

)) ; =>`#t`

(`arity-at-least-value`

(`procedure-arity`

`list`

)) ; =>`0`

(`arity-at-least-value`

(`procedure-arity`

(lambda (x . y) x))) ; =>`1`

(`procedure-arity`

(case-lambda [(x) 0] [(x y) 1])) ; =>`'(1 2)`

(`procedure-arity-includes?`

`cons`

2) ; =>`#t`

(`procedure-arity-includes?`

`display`

3) ; =>`#f`

When compiling a `lambda`

or `case-lambda`

expression,
MzScheme looks for a `'method-arity-error`

property
attached to the expression (see section 12.6.2). If it is present
with a true value, and if no case of the procedure accepts zero
arguments, then the procedure is marked so that an
`exn:application:arity`

exception involving the procedure
will hide the first argument, if one was provided. (Hiding the first
argument is useful when the procedure implements a method, where the
first argument is implicit in the original source). The property
affects only the format of `exn:application:arity`

exceptions,
not the result of

.`procedure-arity`

A **primitive procedure** is a built-in procedure that is
implemented in low-level language. Not all built-in procedures are
primitives, but almost all *R5RS* procedures are primitives, as
are most of the procedures described in this manual.

`(primitive?`

`v`

`)`

returns`#t`

if`v`

is a primitive procedure or`#f`

otherwise.`(primitive-result-arity`

`prim-proc`

`)`

returns the arity of the result of the primitive procedure`prim-proc`

(as opposed to the procedure's input arity as returned by`arity`

; see section 3.10.1). For most primitives, this procedure returns`1`

, since most primitives return a single value when applied. For information about arity values, see section 3.10.1.`(primitive-closure?`

`v`

`)`

returns`#t`

if`v`

is internally implemented as a primitive closure rather than an simple primitive procedure,`#f`

otherwise. This information is intended for use by thecompiler.**mzc**

See section 6.2.4 for information about the names of primitives,
and the names inferred for `lambda`

and `case-lambda`

procedures.

The `force`

procedure can only be applied to values returned
by `delay`

, and promises are never implicitly

d.`force`

`(promise?`

` ``v`

`)`

returns `#t`

if `v`

is a promise
created by `delay`

, `#f`

otherwise.

`(make-hash-table`

` `[`flag-symbol flag-symbol`

]`)`

creates and returns a
new hash table. If provided, each `flag-symbol`

must one of
the following:

`'weak`

-- creates a hash table with weakly-held keys (see section 13.1).`'equal`

-- creates a hash table that compares keys using

instead of`equal?`

(needed, for example, when using strings as keys).`eq?`

By default, key comparisons use

. If the second
`eq?`

`flag-symbol`

is redundant, the
`exn:application:mismatch`

exception is raised.

Two hash tables are

if they are created with the same
flags, and if they map the same keys to `equal?`

values (where
``same key'' means either `equal?`

or `eq?`

, depending
on the way the hash table compares keys).`equal?`

`(make-immutable-hash-table`

` ``assoc-list`

` `[`flag-symbol`

]`)`

creates an
immutable hash table. (See also

in
section 3.8.) The `immutable?`

`assoc-list`

must be a list of pairs, where
the

of each pair is a key, and the `car`

is the
corresponding value. The mappings are added to the table in the order
that they appear in `cdr`

`assoc-list`

, so later mappings can hide
earlier mappings. If the optional `flag-symbol`

argument is
provided, it must be `'equal`

, and the created hash table
compares keys with

; otherwise, the created table
compares keys with `equal?`

.`eq?`

`(hash-table?`

` ``v`

` `[`flag-symbol flag-symbol`

]`)`

returns `#t`

if
`v`

was created by

or
`make-hash-table`

`make-immutable-hash-table`

with the given `flag-symbol`

s
(or more), `#f`

otherwise. Each provided `flag-symbol`

must be a distinct flag supported by `make-hash-table`

; if the
second `flag-symbol`

is redundant, the
`exn:application:mismatch`

exception is raised.

`(hash-table-put!`

` ``hash-table key-v v`

`)`

maps `key-v`

to `v`

in `hash-table`

, overwriting any existing mapping for
`key-v`

. If `hash-table`

is immutable, the
`exn:application:type`

exception is raised.

`(hash-table-get`

` ``hash-table key-v`

` `[`failure-thunk`

]`)`

returns the
value for `key-v`

in `hash-table`

. If no value is found for
`key-v`

, then the result of invoking `failure-thunk`

(a
procedure of no arguments) is returned. If `failure-thunk`

is not
provided, the `exn:application:mismatch`

exception is raised when no value is
found for `key-v`

.

`(hash-table-remove!`

` ``hash-table key-v`

`)`

removes the value mapping
for `key-v`

if it exists in `hash-table`

. If
`hash-table`

is immutable, the `en:application:type`

exception is raised.

`(hash-table-map`

` ``hash-table proc`

`)`

applies the procedure `proc`

to each element in `hash-table`

, accumulating the results into a
list. The procedure `proc`

must take two arguments: a key and its
value. See the caveat below about concurrent modification.

`(hash-table-for-each`

` ``hash-table proc`

`)`

applies the procedure
`proc`

to each element in `hash-table`

(for the side-effects
of `proc`

) and returns void. The procedure `proc`

must
take two arguments: a key and its value. See the caveat below about
concurrent modification.

`(hash-table-count`

` ``hash-table`

`)`

returns the number of keys mapped
by `hash-table`

. If `hash-table`

is not created with
`'weak`

, then the result is computed in constant time and
atomically. If `hash-table`

is created with `'weak`

, see
the caveat below about concurrent modification.

`(eq-hash-code`

` ``v`

`)`

returns an exact integer; for any two

values, the returned integer is the same. Furthermore,
for the result integer `eq?`

`k`

and any other exact integer `j`

,
`(= k j)`

implies `(`

.`eq?`

k j)

`(equal-hash-code`

` ``v`

`)`

returns an exact integer; for any two

values, the returned integer is the same.
Furthermore, for the result integer `equal?`

`k`

and any other exact
integer `j`

, `(= k j)`

implies `(`

. If
`eq?`

k j)`v`

contains a cycle through pairs, vectors, boxes, and
inspectable structure fields, then `equal-hash-code`

applied
to `v`

will loop indefinitely.

**Caveat concerning concurrent modification:** A hash table can be
manipulated with

, `hash-table-get`

,
and `hash-table-put!`

concurrently by multiple threads,
and the operations are protected by a table-specific semaphore as
needed. A few caveats apply, however:
`hash-table-remove!`

If a thread is terminated while applying

,`hash-table-get`

, or`hash-table-put!`

to a hash table that uses`hash-table-remove!`

comparisons, all current and future operations on the hash table block indefinitely.`equal?`

The

,`hash-table-map`

, and`hash-table-for-each`

`hash-table-count`

procedures do not use the table's semaphore. Consequently, if a hash table is extended with new keys by another thread while a map or for-each is in process, arbitrary key-value pairs can be dropped or duplicated in the map, for-each, or count. Similarly, if the map or for-each procedure itself extends the table, arbitrary key-value pairs can be dropped or duplicated. However, key mappings can be deleted or remapped by any thread with no adverse affects (i.e., the change does not affect a traversal if the key has been seen already, otherwise the traversal skips a deleted key or uses the remapped key's new value).

**Caveat concerning mutable keys:** If a key into an

-based hash table is mutated (e.g., a key string is
modified with `equal?`

), then the hash table's behavior
for put and get operations becomes unpredictable.`string-set!`

^{2} 30 bits for
a 32-bit architecture, 62 bits for a 64-bit architecture.

^{3} This definition of

technically contradicts `eqv?`

*R5RS*, but *R5RS* does not address
strange ``numbers'' like `+nan.0`

.

^{4} The random number generator uses a
relatively standard Unix `random()` implementation in its
degree-seven polynomial mode.

^{5} All fields of the
`arity-at-least`

structure type are accessible by all
inspectors (see section 4.5).