7.1 Data-structure Contracts
A flat contract can be fully checked immediately for
a given value.
Constructs a
flat contract from
predicate. A value
satisfies the contract if the predicate returns a true value.
On predicates like
flat-contract, but the first argument must be the
(quoted) name of a contract used for error reporting.
For example,
turns the predicate into a contract with the name odd-integer.
On flat contracts, the new flat contract is the same as the old except for
the name.
A flat contract that accepts any value.
When using this contract as the result portion of a function contract,
consider using any instead; using any leads to
better memory performance, but it also allows multiple results.
Takes any number of contracts and returns
a contract that accepts any value that any one of the contracts
accepts individually.
The or/c result tests any value by applying the contracts in
order, from left to right, with the exception that it always moves the
non-flat contracts (if any) to the end, checking them
last. Thus, a contract such as (or/c (not/c real?) positive?) is guaranteed to only invoke the positive?
predicate on real numbers.
If all of the arguments are procedures or flat contracts, the
result is a flat contract. If only one of the arguments is a
higher-order contract, the result is a contract that just checks the
flat contracts and, if they don’t pass, applies the higher-order
contract.
If there are multiple higher-order contracts,
or/c uses
contract-first-order-passes? to distinguish between
them. More precisely, when an
or/c is checked, it first
checks all of the
flat contracts. If none of them pass, it
calls
contract-first-order-passes? with each of the
higher-order contracts. If only one returns true,
or/c uses
that contract. If none of them return true, it signals a contract
violation. If more than one returns true, it also signals a contract
violation.
For example, this contract
does not accept a function like this one:
(lambda args ...)
since it cannot tell which of the two arrow contracts should be used
with the function.
Takes any number of contracts and returns a contract that
accepts any value that satisfies all of the contracts simultaneously.
If all of the arguments are procedures or flat contracts,
the result is a flat contract.
The contract produced by and/c tests any value by applying
the contracts in order, from left to right.
Accepts a flat contracts or a predicate and returns a flat contract
that checks the inverse of the argument.
Returns a flat contract that requires the input to be a number and
= to
z.
Returns a flat contract that requires the input to be a number and
< than
n.
Returns a flat contract that requires the
input to be a real number between n and m or equal to
one of them.
Returns a flat contract that requires the input to be an exact integer
between j and k, inclusive.
A flat contract that requires the input to be an exact non-negative integer.
Returns a flat contract that recognizes strings that have fewer than
len characters.
This is just #f. It is here for backwards compatibility.
A flat contract that recognizes values that can be written out and
read back in with
write and
read.
Accepts any number of atomic values and returns a flat contract that
recognizes those values, using
eqv? as the comparison
predicate. For the purposes of
one-of/c, atomic values are
defined to be: characters, symbols, booleans, null keywords, numbers,
void, and undefined.
Accepts any number of symbols and returns a flat contract that
recognizes those symbols.
Returns a contract that recognizes vectors. The elements of the vector must
match c.
If the flat? argument is #t, then the resulting contract is
a flat contract, and the c argument must also be a flat contract. Such
flat contracts will be unsound if applied to mutable vectors, as they will not
check future operations on the vector.
If the immutable argument is #t and the c argument is
a flat contract, the result will be a flat contract. If the c argument
is a chaperone contract, then the result will be a chaperone contract.
When a higher-order vectorof contract is applied to a vector, the result
is not eq? to the input. The result will be a copy for immutable vectors
and a chaperone or impersonator of the input for mutable vectors.
Returns the same contract as
(vectorof c #:immutable #t). This exists for
reasons of backwards compatibility, and may be removed in the future.
Returns a contract that recognizes vectors whose lengths match the number of
contracts given. Each element of the vector must match its corresponding contract.
If the flat? argument is #t, then the resulting contract is
a flat contract, and the c arguments must also be flat contracts. Such
flat contracts will be unsound if applied to mutable vectors, as they will not
check future operations on the vector.
If the immutable argument is #t and the c arguments are
flat contracts, the result will be a flat contract. If the c arguments
are chaperone contracts, then the result will be a chaperone contract.
When a higher-order vector/c contract is applied to a vector, the result
is not eq? to the input. The result will be a copy for immutable vectors
and a chaperone or impersonator of the input for mutable vectors.
Returns the same contract as
(vector/c c ... #:immutable #t). This exists for
reasons of backwards compatibility, and may be removed in the future.
Returns a contract that recognizes boxes. The content of the box must match c.
If the flat? argument is #t, then the resulting contract is
a flat contract, and the c argument must also be a flat contract. Such
flat contracts will be unsound if applied to mutable boxes, as they will not check
future operations on the box.
If the immutable argument is #t and the c argument is
a flat contract, the result will be a flat contract. If the c argument is
a chaperone contract, then the result will be a chaperone contract.
When a higher-order box/c contract is applied to a box, the result
is not eq? to the input. The result will be a copy for immutable boxes
and either a chaperone or impersonator of the input for mutable boxes.
Returns the same contract as
(box/c c #:immutable #t). This exists for
reasons of backwards compatibility, and may be removed in the future.
Returns a contract that recognizes a list whose every element matches
the contract
c. Beware that when this contract is applied to
a value, the result is not necessarily
eq? to the input.
Returns a contract that recognizes non-empty lists whose elements match
the contract
c. Beware that when this contract is applied to
a value, the result is not necessarily
eq? to the input.
Produces a contract the recognizes pairs whose first and second elements
match
car-c and
cdr-c, respectively. Beware that
when this contract is applied to a value, the result is not
necessarily
eq? to the input.
Produces a contract for a list. The number of elements in the list
must match the number of arguments supplied to
list/c, and
each element of the list must match the corresponding contract. Beware
that when this contract is applied to a value, the result is not
necessarily
eq? to the input.
Produces a flat contract that recognizes syntax objects whose
syntax-e content matches
c.
Produces a contract that recognizes instances of the structure
type named by struct-id, and whose field values match the
contracts produced by the contract-exprs.
Contracts for immutable fields must be either flat or chaperone contracts.
Contracts for mutable fields may be impersonator contracts.
If all fields are immutable and the contract-exprs evaluate
to flat contracts, a flat contract is produced. If all the
contract-exprs are chaperone contracts, a chaperone contract is
produced. Otherwise, an impersonator contract is produced.
Produces a contract on parameters whose values must match
contract.
Produces a contract that recognizes
hash tables with keys and values
as specified by the
key and
val arguments.
If the flat? argument is #t, then the resulting contract is
a flat contract, and the key and val arguments must also be flat
contracts. Such flat contracts will be unsound if applied to mutable hash tables,
as they will not check future operations on the hash table.
If the immutable argument is #t and the key and
val arguments are flat contracts, the result will be a flat contract.
If either the domain or the range is a chaperone contract, then the result will
be a chaperone contract.
If the key argument is a chaperone contract, then the resulting contract
can only be applied to equal?-based hash tables. When a higher-order
hash/c contract is applied to a hash table, the result is not eq?
to the input. The result will be a copy for immutable hash tables, and either a
chaperone or impersonator of the input for mutable hash tables.
Constructs a recursive
flat contract. A
flat-contract-expr can refer to
id to refer
recursively to the generated contract.
For example, the contract
is a flat contract that checks for (a limited form of)
S-expressions. It says that a sexp is either two
sexp combined with cons, or a number, or a symbol.
Note that if the contract is applied to a circular value, contract
checking will not terminate.
A generalization of
flat-rec-contract for defining several
mutually recursive flat contracts simultaneously. Each
id is
visible in the entire
flat-murec-contract form, and the
result of the final
body is the result of the entire form.
Represents a contract that is always satisfied. In particular, it can accept
multiple values. It can only be used in a result position of contracts like
->. Using
any elsewhere is a syntax error.
Constructs a contract on a promise. The contract does not force the
promise, but when the promise is forced, the contract checks that the
result value meets the contract produced by expr.
Constructs a new universal contract.
Universal contracts accept all values when in negative positions (e.g., function
inputs) and wrap them in an opaque struct, hiding the precise value.
In positive positions (e.g. function returns),
a universal contract accepts only values that were previously accepted in negative positions (by checking
for the wrappers).
The name is used to identify the contract in error messages.
For example, this contract:
describes the identity function (or a non-terminating function)
That is, the first use of the a appears in a
negative position and thus inputs to that function are wrapped with an opaque struct.
Then, when the function returns, it is checked to determine whether the result is wrapped, since
the second a appears in a positive position.
This is a dual to new-∃/c.
Constructs a new existential contract.
Existential contracts accept all values when in positive positions (e.g., function
returns) and wrap them in an opaque struct, hiding the precise value.
In negative positions (e.g. function inputs),
they accepts only values that were previously accepted in positive positions (by checking
for the wrappers).
The name is used to identify the contract in error messages.
For example, this contract:
describes a function that accepts the identity function (or a non-terminating function)
and returns an arbitrary value. That is, the first use of the a appears in a
positive position and thus inputs to that function are wrapped with an opaque struct.
Then, when the function returns, it is checked to see if the result is wrapped, since
the second a appears in a negative position.
This is a dual to new-∀/c.