8.1 Data-structure Contracts

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 8 | Contracts

8.1 | Data-structure Contracts
8.2 | Function Contracts
8.3 | Parametric Contracts
8.4 | Lazy Data-structure Contracts
8.5 | Structure Type Property Contracts
8.6 | Attaching Contracts to Values
8.7 | Building New Contract Combinators
8.8 | Contract Utilities
8.9 | racket/ contract/ base
8.10 | Collapsible Contracts
8.11 | Legacy Contracts
8.12 | Random generation

On this page:

flat-contract-with-explanation
flat-named-contract
any/ c
none/ c
or/ c
first-or/ c
and/ c
not/ c
=/ c
</ c
>/ c
<=/ c
>=/ c
between/ c
real-in
integer-in
complex/ c
char-in
natural-number/ c
string-len/ c
false/ c
printable/ c
one-of/ c
symbols
vectorof
vector-immutableof
vector/ c
vector-immutable/ c
box/ c
box-immutable/ c
listof
non-empty-listof
list*of
cons/ c
cons/ dc
list/ c
*list/ c
treelist/ c
mutable-treelist/ c
syntax/ c
struct/ c
struct/ dc
parameter/ c
procedure-arity-includes/ c
hash/ c
hash/ dc
channel/ c
prompt-tag/ c
continuation-mark-key/ c
evt/ c
flat-rec-contract
flat-murec-contract
any
promise/ c
flat-contract
flat-contract-predicate
property/ c
suggest/ c

top contents ← prev up next →

#### 8.1`` Data-structure Contracts🔗ℹ

> > procedure
> > (flat-contract-with-explanation |  | get-explanation |
> > | [ | #:name name]) |
> → flat-contract?
> get-explanation : (-> any/c (or/c boolean? (-> blame? any)))
> name : any/c = (object-name get-explanation)

Provides a way to use flat contracts that, when a contract fails, provide more information about the failure.

If get-explanation returns a boolean, then that boolean value is treated as the predicate in a flat contract. If it returns a procedure, then it is treated similarly to returning #f, except the result procedure is called to actually signal the contract violation.

The name argument is used as the name of the contract; it defaults to the name of the get-explanation function.

> (flat-contract-with-explanation
> (λ (val)
> (cond
> [(even? val) #t]
> [else
> (λ (blame)
> (define more-information ...do-some-complex-computation-here...)
> (raise-blame-error blame val
> '(expected: "an even number" given: "~e"
> "and, here is more help: ~s")
> val more-information))])))

> > procedure
> > (flat-named-contract |  | name |  |  |  |
> > |  | flat-contract |  |  |  |
> > | [ | generator]) |  | → |  | flat-contract?
> name : any/c
> flat-contract : flat-contract?
> | generator |  | : |  | (or/c #f (-> exact-nonnegative-integer? (-> any/c)))
> |  |  | = |  | #f

Produces a flat contract like flat-contract, but with the name name.

For example,

> (define/contract i
> (flat-named-contract
> 'odd-integer
> (lambda (x) (and (integer? x) (odd? x))))
> 2)

The generator argument adds a generator for the flat-named-contract. See contract-random-generate for more information.

> value any/c : flat-contract?

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.

> value none/c : flat-contract?

A flat contract that accepts no values.

> procedure (or/c contract ...) → contract?
> contract : contract?

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

> (or/c (-> number? number?)
> (-> string? string? string?))

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.

If all of its arguments are list-contract?s, then or/c returns a list-contract?.

> procedure (first-or/c contract ...) → contract?
> contract : contract?

Takes any number of contracts and returns a contract that accepts any value that any one of the contracts accepts individually.

The first-or/c result tests any value by applying the contracts in order from left to right. Thus, a contract such as (first-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 and similarly if all of the arguments are chaperone contracts the result is too. Otherwise, the result is an impersonator contract.

If there are multiple higher-order contracts, first-or/c uses contract-first-order-passes? to distinguish between them. More precisely, when an first-or/c is checked, it checks the first order passes of the first contract against the value. If it succeeds, then it uses only that contract. If it fails, then it moves to the second contract, continuing until it finds one of the contracts where the first order check succeeds. If none of them do, a contract violation is signaled.

For example, this contract

> (first-or/c (-> number? number?)
> (-> string? string? string?))

accepts the function (λ args 0), applying the (-> number? number?) contract to the function because it comes first, even though (-> string? string? string?) also applies.

If all of its arguments are list-contract?s, then first-or/c returns a list-contract?.

> procedure (and/c contract ...) → contract?
> contract : contract?

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.

This means that and/c can be used to guard predicates that are not total in contracts. For example, this contract is well-behaved, correctly blaming the definition of whoops-not-a-number for not being a number:

Example:

> > (define/contract whoops-not-a-number
> (and/c real? even?)
> "four")
> whoops-not-a-number: broke its own contract
> promised: real?
> produced: "four"
> in: an and/c case of
> (and/c real? even?)
> contract from:
> (definition whoops-not-a-number)
> blaming: (definition whoops-not-a-number)
> (assuming the contract is correct)
> at: eval:2:0

but if the arguments to and/c are reversed, then the contract itself raises an error:

Example:

> > (define/contract whoops-not-a-number
> (and/c even? real?)
> "four")
> even?: contract violation
> expected: integer?
> given: "four"

If more than one of the contracts are not flat contracts, then the order in which the higher-order parts of the contract are tested can be counter-intuitive. As an example, consider this function that uses and/c in a higher-order manner with contracts that always succeed, but that print when they are called, in order for us to see the order in which they are called.

Examples:

> > (define ((show-me n) x)
> (printf "show-me ~a\n" n)
> #t)
> > (define/contract identity-with-complex-printing-contract
> (and/c (-> (show-me 4) (show-me 5))
> (-> (show-me 3) (show-me 6))
> (-> (show-me 2) (show-me 7))
> (-> (show-me 1) (show-me 8)))
> (λ (x) x))
> > (identity-with-complex-printing-contract 101)
> show-me 1
> show-me 2
> show-me 3
> show-me 4
> show-me 5
> show-me 6
> show-me 7
> show-me 8
> 101

The checking order is just like the usual ordering when a contract is double-wrapped. The contract that is first put on has its domain checked second but its range checked first and we see a similar pattern here in this example, because and/c simply applies the contracts in order.

> procedure (not/c flat-contract) → flat-contract?
> flat-contract : flat-contract?

Accepts a flat contract or a predicate and returns a flat contract that checks the inverse of the argument.

> procedure (=/c z) → flat-contract?
> z : real?

Returns a flat contract that requires the input to be a number and = to z.

> procedure (</c n) → flat-contract?
> n : real?

Returns a flat contract that requires the input to be a number and < than n.

> procedure (>/c n) → flat-contract?
> n : real?

Like </c, but for >.

> procedure (<=/c n) → flat-contract?
> n : real?

Like </c, but for <=.

> procedure (>=/c n) → flat-contract?
> n : real?

Like </c, but for >=.

> procedure (between/c n m) → flat-contract?
> n : real?
> m : real?

Returns a flat contract that requires the input to be a real number between n and m or equal to one of them.

> procedure (real-in n m) → flat-contract?
> n : real?
> m : real?

An alias for between/c.

> procedure (integer-in j k) → flat-contract?
> j : (or/c exact-integer? #f)
> k : (or/c exact-integer? #f)

Returns a flat contract that requires the input to be an exact integer between j and k, inclusive. If either j or k is #f, then the range is unbounded on that end.

Examples:

> > (define/contract two-digit-number
> (integer-in 10 99)
> 23)
> > (define/contract not-a-two-digit-number
> (integer-in 10 99)
> 124)
> not-a-two-digit-number: broke its own contract
> promised: (integer-in 10 99)
> produced: 124
> in: (integer-in 10 99)
> contract from:
> (definition not-a-two-digit-number)
> blaming: (definition not-a-two-digit-number)
> (assuming the contract is correct)
> at: eval:3:0
> > (define/contract negative-number
> (integer-in #f -1)
> -4)
> > (define/contract not-a-negative-number
> (integer-in #f -1)
> 4)
> not-a-negative-number: broke its own contract
> promised: (integer-in #f -1)
> produced: 4
> in: (integer-in #f -1)
> contract from:
> (definition not-a-negative-number)
> blaming: (definition not-a-negative-number)
> (assuming the contract is correct)
> at: eval:5:0

Changed in version 6.8.0.2 of package base: Allow j and k to be #f

> procedure (complex/c real imag) → flat-contract?
> real : flat-contract?
> imag : flat-contract?

Returns a flat contract that accepts complex numbers whose real parts match real and whose imaginary parts match imag.

Examples:

> > (define/contract can-be-converted-to-exact
> (complex/c rational? rational?)
> +inf.0)
> can-be-converted-to-exact: broke its own contract
> promised: a complex number with
> real part: rational?
> imaginary part: rational?
> produced: +inf.0
> in: (complex/c rational? rational?)
> contract from:
> (definition can-be-converted-to-exact)
> blaming: (definition can-be-converted-to-exact)
> (assuming the contract is correct)
> at: eval:2:0
> > (define/contract complex-integer
> (complex/c integer? integer?)
> 1+2i)

Added in version 8.11.1.10 of package base.

> procedure (char-in a b) → flat-contract?
> a : char?
> b : char?

Returns a flat contract that requires the input to be a character whose code point number is between the code point numbers of a and b, inclusive.

> value natural-number/c : flat-contract?

A flat contract that requires the input to be an exact non-negative integer.

> procedure (string-len/c len) → flat-contract?
> len : real?

Returns a flat contract that recognizes strings that have fewer than len characters.

> value false/c : flat-contract?

An alias for #f for backwards compatibility.

> value printable/c : flat-contract?

A flat contract that recognizes values that can be written out and read back in with write and read.

> procedure (one-of/c v ...+) → flat-contract?
> v : any/c

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

This is a backwards compatibility contract constructor. If neither #<void> nor #<undefined> are arguments, it simply passes its arguments to or/c.

> procedure (symbols sym ...+) → flat-contract?
> sym : symbol?

Accepts any number of symbols and returns a flat contract that recognizes those symbols.

This is a backwards compatibility constructor; it merely passes its arguments to or/c.

> > procedure
> > (vectorof |  | c |  |  |  |
> > | [ | #:immutable immutable |  |  |  |
> > |  | #:flat? flat? |  |  |  |
> > |  | #:eager eager]) |  | → |  | contract?
> c : contract?
> immutable : (or/c #t #f 'dont-care) = 'dont-care
> flat? : boolean? = #f
> eager : (or/c #t #f exact-nonnegative-integer?) = #t

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 and the eager argument is #t, the result will be a flat contract. If the c argument is a chaperone contract, then the result will be a chaperone contract.

If the eager argument is #t, then immutable vectors are checked eagerly when c is a flat contract. If the eager argument is a number n, then immutable vectors are checked eagerly when c is a flat contract and the length of the vector is less than or equal to n.

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, unless the c argument is a flat contract and the vector is immutable, in which case the result is the original vector.

Changed in version 6.3.0.5 of package base: Changed flat vector contracts to not copy immutable vectors.
Changed in version 6.7.0.3: Added the #:eager option.

> procedure (vector-immutableof c) → contract?
> c : contract?

Returns the same contract as (vectorof c #:immutable #t). This form exists for backwards compatibility.

> > procedure
> > (vector/c |  | c |  |  |  |
> > |  | ... |  |  |  |
> > | [ | #:immutable immutable |  |  |  |
> > |  | #:flat? flat?]) |  | → |  | contract?
> c : contract?
> immutable : (or/c #t #f 'dont-care) = 'dont-care
> flat? : boolean? = #f

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.

> procedure (vector-immutable/c c ...) → contract?
> c : contract?

Returns the same contract as (vector/c c ... #:immutable #t). This form exists for reasons of backwards compatibility.

> > procedure
> > (box/c |  | in-c |  |  |  |
> > | [ | c |  |  |  |
> > |  | #:immutable immutable |  |  |  |
> > |  | #:flat? flat?]) |  | → |  | contract?
> in-c : contract?
> c : contract? = in-c
> immutable : (or/c #t #f 'dont-care) = 'dont-care
> flat? : boolean? = #f

Returns a contract that recognizes boxes. The content of the box must match c, and mutations on mutable boxes must match in-c.

If the flat? argument is #t, then the resulting contract is a flat contract, and the out 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.

> procedure (box-immutable/c c) → contract?
> c : contract?

Returns the same contract as (box/c c #:immutable #t). This form exists for reasons of backwards compatibility.

> procedure (listof c) → list-contract?
> c : contract?

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.

Examples:

> > (define/contract some-numbers
> (listof number?)
> (list 1 2 3))
> > (define/contract just-one-number
> (listof number?)
> 11)
> just-one-number: broke its own contract
> promised: list?
> produced: 11
> in: (listof number?)
> contract from: (definition just-one-number)
> blaming: (definition just-one-number)
> (assuming the contract is correct)
> at: eval:3:0

> procedure (non-empty-listof c) → list-contract?
> c : contract?

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.

Examples:

> > (define/contract some-numbers
> (non-empty-listof number?)
> (list 1 2 3))
> > (define/contract not-enough-numbers
> (non-empty-listof number?)
> (list))
> not-enough-numbers: broke its own contract
> promised: (and/c list? pair?)
> produced: '()
> in: (non-empty-listof number?)
> contract from:
> (definition not-enough-numbers)
> blaming: (definition not-enough-numbers)
> (assuming the contract is correct)
> at: eval:3:0

> procedure (list*of ele-c [last-c]) → contract?
> ele-c : contract?
> last-c : contract? = ele-c

Returns a contract that recognizes improper lists whose elements match the contract ele-c and whose last position matches last-c. If an improper list is created with cons, then its car position is expected to match ele-c and its cdr position is expected to be (list*of ele-c list-c). Otherwise, it is expected to match last-c. Beware that when this contract is applied to a value, the result is not necessarily eq? to the input.

Examples:

> > (define/contract improper-numbers
> (list*of number?)
> (cons 1 (cons 2 3)))
> > (define/contract not-improper-numbers
> (list*of number?)
> (list 1 2 3))
> not-improper-numbers: broke its own contract
> promised: number?
> produced: '()
> in: an element of
> (list*of number?)
> contract from:
> (definition not-improper-numbers)
> blaming: (definition not-improper-numbers)
> (assuming the contract is correct)
> at: eval:3:0

Added in version 6.1.1.1 of package base.
Changed in version 6.4.0.4: Added the last-c argument.

> procedure (cons/c car-c cdr-c) → contract?
> car-c : contract?
> cdr-c : contract?

Produces a contract that 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.

If the cdr-c contract is a list-contract?, then cons/c returns a list-contract?.

Examples:

> > (define/contract a-pair-of-numbers
> (cons/c number? number?)
> (cons 1 2))
> > (define/contract not-a-pair-of-numbers
> (cons/c number? number?)
> (cons #f #t))
> not-a-pair-of-numbers: broke its own contract
> promised: number?
> produced: #f
> in: the car of
> (cons/c number? number?)
> contract from:
> (definition not-a-pair-of-numbers)
> blaming: (definition not-a-pair-of-numbers)
> (assuming the contract is correct)
> at: eval:3:0

Changed in version 6.0.1.13 of package base: Added the list-contract? propagating behavior.

> syntax (cons/dc [car-id contract-expr] [cdr-id (car-id) contract-expr] cons/dc-option)
> (cons/dc [car-id (cdr-id) contract-expr] [cdr-id contract-expr] cons/dc-option)
> cons/dc-option |  | = |  |
> |  | | |  | #:flat
> |  | | |  | #:chaperone
> |  | | |  | #:impersonator

Produces a contract that recognizes pairs whose first and second elements match the expressions after car-id and cdr-id, respectively.

In the first case, the contract on the cdr-id portion of the contract may depend on the value in the car-id portion of the pair and in the second case, the reverse is true.

Examples:

> > (define/contract an-ordered-pair-of-reals
> (cons/dc [hd real?] [tl (hd) (>=/c hd)])
> (cons 1 2))
> > (define/contract not-an-ordered-pair-of-reals
> (cons/dc [hd real?] [tl (hd) (>=/c hd)])
> (cons 2 1))
> not-an-ordered-pair-of-reals: broke its own contract
> promised: (>=/c 2)
> produced: 1
> in: the cdr of
> (cons/dc (hd real?) (tl (hd) (>=/c hd)))
> contract from:
> (definition not-an-ordered-pair-of-reals)
> blaming: (definition not-an-ordered-pair-of-reals)
> (assuming the contract is correct)
> at: eval:3:0

Added in version 6.1.1.6 of package base.

> procedure (list/c c ...) → list-contract?
> c : contract?

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.

> procedure (*list/c prefix suffix ...) → list-contract?
> prefix : contract?
> suffix : contract?

Produces a contract for a list. The number of elements in the list must be at least as long as the number of suffix contracts and the tail of the list must match those contracts, one for each element. The beginning portion of the list can be arbitrarily long, and each element must match prefix.

Beware that when this contract is applied to a value, the result is not necessarily eq? to the input.

Examples:

> > (define/contract a-list-of-numbers-ending-with-two-integers
> (*list/c number? integer? integer?)
> (list 1/2 4/5 0+1i -11 322))
> > (define/contract not-enough-integers-at-the-end
> (*list/c number? integer? integer? integer?)
> (list 1/2 4/5 1/2 321 322))
> not-enough-integers-at-the-end: broke its own contract
> promised: integer?
> produced: 1/2
> in: the 3rd to the last element of
> (*list/c number? integer? integer? integer?)
> contract from:
> (definition not-enough-integers-at-the-end)
> blaming: (definition not-enough-integers-at-the-end)
> (assuming the contract is correct)
> at: eval:3:0

> procedure (treelist/c ctc [#:flat? flat? #:lazy? lazy?]) → contract?
> ctc : contract?
> flat? : any/c = (flat-contract? ctc)
> | lazy? |  | : |  | any/c |  | = |  |
> (cond
> [(flat-contract? ctc) #f]
> [(chaperone-contract? ctc) #t]
> [else #f])

Produces a contract for treelists whose elements match ctc.

If flat? is a true value then ctc must be a flat contract. In that situation, the result of treelist/c will also be a flat contract.

If lazy? is a true value, then ctc must be a chaperone contract and the resulting contract will be a chaperone contract. In that situation, the contracts on the elements of the tree list are not checked until the values are accessed.

If both flat? and lazy? are #f, then the contract will copy the tree list as part of the process of checking the contract and the result will be a chaperone contract if ctc is a chaperone contract.

At least one of flat? and lazy? must be #f.

Examples:

> > (define/contract natural-treelist
> (treelist/c natural?)
> (treelist 1 2 3))
> > (define/contract unnatural-treelist
> (treelist/c natural?)
> (treelist -1 -2 -3))
> unnatural-treelist: broke its own contract
> promised: natural?
> produced: -1
> in: the elements of
> (treelist/c natural?)
> contract from:
> (definition unnatural-treelist)
> blaming: (definition unnatural-treelist)
> (assuming the contract is correct)
> at: eval:3:0

Added in version 8.12.0.7 of package base.

> procedure (mutable-treelist/c ctc) → contract?
> ctc : contract?

Produces a contract for mutable treelists whose elements match ctc.

Examples:

> > (define/contract natural-treelist
> (mutable-treelist/c natural?)
> (mutable-treelist 0 1 2 3))
> > (mutable-treelist-ref natural-treelist 1)
> 1
> > (define/contract unnatural-treelist
> (mutable-treelist/c natural?)
> (mutable-treelist -1 2 3))
> > (mutable-treelist-ref unnatural-treelist 0)
> unnatural-treelist: broke its own contract
> promised: natural?
> produced: -1
> in: the elements of
> (mutable-treelist/c natural?)
> contract from:
> (definition unnatural-treelist)
> blaming: (definition unnatural-treelist)
> (assuming the contract is correct)
> at: eval:4:0
> > (mutable-treelist-set! unnatural-treelist 2 -3)
> unnatural-treelist: contract violation
> expected: natural?
> given: -3
> in: the elements of
> (mutable-treelist/c natural?)
> contract from:
> (definition unnatural-treelist)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:4:0

Added in version 8.12.0.11 of package base.

> procedure (syntax/c c) → flat-contract?
> c : flat-contract?

Produces a flat contract that recognizes syntax objects whose syntax-e content matches c.

> syntax (struct/c struct-id contract-expr ...)

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.

> syntax (struct/dc struct-id field-spec ... maybe-inv)
> field-spec |  | = |  | [field-name maybe-lazy contract-expr]
> [field-name (dep-field-name ...)
> maybe-lazy
> maybe-contract-type
> maybe-dep-state
> contract-expr]
> field-name |  | = |  | field-id
> |  | | |  | (#:selector selector-id)
> |  | | |  | (field-id #:parent struct-id)
> maybe-lazy |  | = |  |
> |  | | |  | #:lazy
> maybe-contract-type |  | = |  |
> |  | | |  | #:flat
> |  | | |  | #:chaperone
> |  | | |  | #:impersonator
> maybe-dep-state |  | = |  |
> |  | | |  | #:depends-on-state
> maybe-inv |  | = |  |
> |  | | |  | #:inv (dep-field-name ...) invariant-expr

Produces a contract that recognizes instances of the structure type named by struct-id, and whose field values match the contracts produced by the field-specs.

If the field-spec lists the names of other fields, then the contract depends on values in those fields, and the contract-expr expression is evaluated each time a selector is applied, building a new contract for the fields based on the values of the dep-field-name fields (the dep-field-name syntax is the same as the field-name syntax). If the field is a dependent field and no contract-type annotation appears, then it is assumed that the contract is a chaperone, but not always a flat contract (and thus the entire struct/dc contract is not a flat contract). If this is not the case, and the contract is always flat then the field must be annotated with the #:flat, or the field must be annotated with #:impersonator (in which case, it must be a mutable field).

A field-name is either an identifier naming a field in the first case, an identifier naming a selector in the second case indicated by the #:selector keyword, or a field id for a struct that is a parent of struct-id, indicated by the #:parent keyword.

If the #:lazy keyword appears, then the contract on the field is checked lazily (only when a selector is applied); #:lazy contracts cannot be put on mutable fields.

If a dependent contract depends on some mutable state, then use the #:depends-on-state keyword argument (if a field’s dependent contract depends on a mutable field, this keyword is automatically inferred). The presence of this keyword means that the contract expression is evaluated each time the corresponding field is accessed (or mutated, if it is a mutable field). Otherwise, the contract expression for a dependent field contract is evaluated when the contract is applied to a value.

If the #:inv clause appears, then the invariant expression is evaluated (and must return a non-#f value) when the contract is applied to a struct.

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.

As an example, the function bst/c below returns a contract for binary search trees whose values are all between lo and hi. The lazy annotations ensure that this contract does not change the running time of operations that do not inspect the entire tree.

Examples:

> > (struct bt (val left right))
> > (define (bst/c lo hi)
> (or/c #f
> (struct/dc bt
> [val (between/c lo hi)]
> [left (val) #:lazy (bst/c lo val)]
> [right (val) #:lazy (bst/c val hi)])))
> > (define/contract not-really-a-bst
> (bst/c -inf.0 +inf.0)
> (bt 5
> (bt 4
> (bt 2 #f #f)
> (bt 6 #f #f))
> #f))
> > (bt-right not-really-a-bst)
> #f
> > (bt-val (bt-left (bt-left not-really-a-bst)))
> 2
> > (bt-right (bt-left not-really-a-bst))
> not-really-a-bst: broke its own contract
> promised: (between/c 4 5)
> produced: 6
> in: the val field of
> a part of the or/c of
> the right field of
> a part of the or/c of
> the left field of
> a part of the or/c of
> (or/c
> #f
> (struct/dc
> bt
> (val (between/c -inf.0 +inf.0))
> (left (val) #:lazy ...)
> (right (val) #:lazy ...)))
> contract from: (definition not-really-a-bst)
> blaming: (definition not-really-a-bst)
> (assuming the contract is correct)
> at: eval:4:0

Changed in version 6.0.1.6 of package base: Added #:inv.

> > procedure
> > (parameter/c |  | in |  |  |  |
> > | [ | out |  |  |  |
> > |  | #:impersonator? impersonator?]) |  | → |  | contract?
> in : contract?
> out : contract? = in
> impersonator? : any/c = #t

Produces a contract on parameters whose values must match out. When the value in the contracted parameter is set, it must match in.

If impersonator? is a true value, then parameter/c always returns an impersonator contract. If it is #f, then the result will be a chaperone contract when both in and out are chaperone contracts, and an impersonator contract otherwise.

Examples:

> > (define/contract current-snack
> (parameter/c string?)
> (make-parameter "potato-chip"))
> > (define baked/c
> (flat-named-contract 'baked/c (λ (s) (regexp-match #rx"baked" s))))
> > (define/contract current-dinner
> (parameter/c string? baked/c)
> (make-parameter "turkey" (λ (s) (string-append "roasted " s))))
> > (current-snack 'not-a-snack)
> current-snack: contract violation
> expected: string?
> given: 'not-a-snack
> in: the parameter of
> (parameter/c string?)
> contract from: (definition current-snack)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:2:0
> > (parameterize ([current-dinner "tofurkey"])
> (current-dinner))
> current-dinner: broke its own contract
> promised: baked/c
> produced: "roasted tofurkey"
> in: the parameter of
> (parameter/c string? baked/c)
> contract from: (definition current-dinner)
> blaming: (definition current-dinner)
> (assuming the contract is correct)
> at: eval:4:0

> procedure (procedure-arity-includes/c n) → flat-contract?
> n : exact-nonnegative-integer?

Produces a contract for procedures that accept n argument (i.e,. the procedure? contract is implied).

> > procedure
> > (hash/c |  | key |  |  |  |
> > |  | val |  |  |  |
> > | [ | #:immutable immutable |  |  |  |
> > |  | #:flat? flat?]) |  | → |  | contract?
> key : chaperone-contract?
> val : contract?
> immutable : (or/c #t #f 'dont-care) = 'dont-care
> flat? : boolean? = #f

Produces a contract that recognizes hash tables with keys and values as specified by the key and val arguments.

Examples:

> > (define/contract good-hash
> (hash/c integer? boolean?)
> (hash 1 #t
> 2 #f
> 3 #t))
> > (define/contract bad-hash
> (hash/c integer? boolean?)
> (hash 1 "elephant"
> 2 "monkey"
> 3 "manatee"))
> bad-hash: broke its own contract
> promised: boolean?
> produced: "elephant"
> in: the values of
> (hash/c integer? boolean?)
> contract from: (definition bad-hash)
> blaming: (definition bad-hash)
> (assuming the contract is correct)
> at: eval:3:0

There are a number of technicalities that control how hash/c contracts behave.

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

  Examples:

  > > (flat-contract? (hash/c integer? boolean?))
  > #f
  > > (flat-contract? (hash/c integer? boolean? #:flat? #t))
  > #t
  > > (hash/c integer? (-> integer? integer?) #:flat? #t)
  > hash/c: contract violation
  > expected: flat-contract?
  > given: (-> integer? integer?)

  Such flat contracts will be unsound if applied to mutable hash tables, as they will not check future mutations to the hash table.

  Examples:

  > > (define original-h (make-hasheq))
  > > (define/contract ctc-h
  > (hash/c integer? boolean? #:flat? #t)
  > original-h)
  > > (hash-set! original-h 1 "not a boolean")
  > > (hash-ref ctc-h 1)
  > "not a boolean"

- If the immutable argument is #t and the key and val arguments are flat-contract?s, the result will be a flat-contract?.

  Example:

  > > (flat-contract? (hash/c integer? boolean? #:immutable #t))
  > #t

  If either the domain or the range is a chaperone-contract?, then the result will be a chaperone-contract?.

  Examples:

  > > (flat-contract? (hash/c (-> integer? integer?) boolean?
  > #:immutable #t))
  > #f
  > > (chaperone-contract? (hash/c (-> integer? integer?) boolean?
  > #:immutable #t))
  > #t

- If the key argument is a chaperone-contract? but not a flat-contract?, then the resulting contract can be applied only to equal?-based hash tables.

  Example:

  > > (define/contract h
  > (hash/c (-> integer? integer?) any/c)
  > (make-hasheq))
  > h: broke its own contract;
  > promised equal?-based hash table due to higher-order domain
  > contract
  > produced: '#hasheq()
  > in: (hash/c (-> integer? integer?) any/c)
  > contract from: (definition h)
  > blaming: (definition h)
  > (assuming the contract is correct)
  > at: eval:2:0

  Also, when such a hash/c contract is applied to a hash table, the result is not eq? to the input. The result of applying the contract will be a copy for immutable hash tables, and either a chaperone or impersonator of the original hash table for mutable hash tables.

> > syntax
> > (hash/dc [key-id key-contract-expr] [value-id (key-id) value-contract-expr]
> > hash/dc-option)
> hash/dc-option |  | = |  |
> |  | | |  | #:immutable immutable?-expr hash/dc-option
> |  | | |  | #:kind kind-expr hash/dc-option

Creates a contract for hash? tables with keys matching key-contract-expr and where the contract on the values can depend on the key itself, since key-id will be bound to the corresponding key before evaluating the values-contract-expr.

If immutable?-expr is #t, then only immutable? hashes are accepted. If it is #f then immutable? hashes are always rejected. It defaults to 'dont-care, in which case both mutable and immutable hashes are accepted.

If kind-expr evaluates to 'flat, then key-contract-expr and value-contract-expr are expected to evaluate to flat-contract?s. If it is 'chaperone, then they are expected to be chaperone-contract?s, and it may also be 'impersonator, in which case they may be any contract?s. The default is 'chaperone.

Examples:

> > (define/contract h
> (hash/dc [k real?] [v (k) (>=/c k)])
> (hash 1 3
> 2 4))
> > (define/contract h
> (hash/dc [k real?] [v (k) (>=/c k)])
> (hash 3 1
> 4 2))
> h: broke its own contract
> promised: (>=/c 3)
> produced: 1
> in: the values of
> (hash/dc (k real?) (v (k) (>=/c k)))
> contract from: (definition h)
> blaming: (definition h)
> (assuming the contract is correct)
> at: eval:3:0

> procedure (channel/c val) → contract?
> val : contract?

Produces a contract that recognizes channels that communicate values as specified by the val argument.

If the val argument is a chaperone contract, then the resulting contract is a chaperone contract. Otherwise, the resulting contract is an impersonator contract. When a channel contract is applied to a channel, the resulting channel is not eq? to the input.

Examples:

> > (define/contract chan
> (channel/c string?)
> (make-channel))
> > (thread (λ () (channel-get chan)))
> #<thread>
> > (channel-put chan 'not-a-string)
> chan: contract violation
> expected: string?
> given: 'not-a-string
> in: (channel/c string?)
> contract from: (definition chan)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:2:0

> syntax (prompt-tag/c contract ... maybe-call/cc)
> maybe-call/cc |  | = |  |
> |  | | |  | #:call/cc contract
> |  | | |  | #:call/cc (values contract ...)
> | contract |  | : |  | contract?

Takes any number of contracts and returns a contract that recognizes continuation prompt tags and will check any aborts or prompt handlers that use the contracted prompt tag.

Each contract will check the corresponding value passed to an abort-current-continuation and handled by the handler of a call to call-with-continuation-prompt.

If all of the contracts are chaperone contracts, the resulting contract will also be a chaperone contract. Otherwise, the contract is an impersonator contract.

If maybe-call/cc is provided, then the provided contracts are used to check the return values from a continuation captured with call-with-current-continuation.

Examples:

> > (define/contract tag
> (prompt-tag/c (-> number? string?))
> (make-continuation-prompt-tag))
> > (call-with-continuation-prompt
> (lambda ()
> (number->string
> (call-with-composable-continuation
> (lambda (k)
> (abort-current-continuation tag k)))))
> tag
> (lambda (k) (k "not a number")))
> tag: contract violation
> expected: number?
> given: "not a number"
> in: the 1st argument of
> (prompt-tag/c
> (-> number? string?)
> #:call/cc)
> contract from: (definition tag)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:2:0

> procedure (continuation-mark-key/c contract) → contract?
> contract : contract?

Takes a single contract and returns a contract that recognizes continuation marks and will check any mappings of marks to values or any accesses of the mark value.

If the argument contract is a chaperone contract, the resulting contract will also be a chaperone contract. Otherwise, the contract is an impersonator contract.

Examples:

> > (define/contract mark-key
> (continuation-mark-key/c (-> symbol? (listof symbol?)))
> (make-continuation-mark-key))
> > (with-continuation-mark
> mark-key
> (lambda (s) (append s '(truffle fudge ganache)))
> (let ([mark-value (continuation-mark-set-first
> (current-continuation-marks) mark-key)])
> (mark-value "chocolate-bar")))
> mark-key: contract violation
> expected: symbol?
> given: "chocolate-bar"
> in: the 1st argument of
> (continuation-mark-key/c
> (-> symbol? (listof symbol?)))
> contract from: (definition mark-key)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:2:0

> procedure (evt/c contract ...) → chaperone-contract?
> contract : chaperone-contract?

Returns a contract that recognizes synchronizable events whose synchronization results are checked by the given contracts.

The resulting contract is always a chaperone contract and its arguments must all be chaperone contracts.

Examples:

> > (define/contract my-evt
> (evt/c evt?)
> always-evt)
> > (define/contract failing-evt
> (evt/c number? number?)
> (alarm-evt (+ (current-inexact-milliseconds) 50)))
> > (sync my-evt)
> #<always-evt>
> > (sync failing-evt)
> failing-evt: broke its own contract
> promised: event that produces 2 values
> produced: event that produces 1 values
> in: (evt/c number? number?)
> contract from: (definition failing-evt)
> blaming: (definition failing-evt)
> (assuming the contract is correct)
> at: eval:3:0

> syntax (flat-rec-contract id flat-contract-expr ...)

Constructs a recursive flat contract. A flat-contract-expr can refer to id to refer recursively to the generated contract.

For example, the contract

> (flat-rec-contract sexp
> (cons/c sexp sexp)
> number?
> symbol?)

is a flat contract that checks for (a limited form of) S-expressions. It says that a sexp is either two sexps 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.

> syntax (flat-murec-contract ([id flat-contract-expr ...] ...) body ...+)

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.

> syntax any

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.

> procedure (promise/c c) → contract?
> c : contract?

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

> procedure (flat-contract predicate) → flat-contract?
> predicate : (-> any/c any/c)

Constructs a flat contract from predicate. A value satisfies the contract if the predicate returns a true value.

This function is a holdover from before predicates could be used directly as flat contracts. It exists today for backwards compatibility.

> procedure (flat-contract-predicate v) → (-> any/c any/c)
> v : flat-contract?

Extracts the predicate from a flat contract.

Note that most flat contracts can be used directly as predicates, but not all. This function can be used to build predicates for ordinary Racket values that double as contracts, such as numbers and symbols. When building a contract combinator that needs to explicitly convert ordinary racket values to flat contracts, consider using coerce-flat-contract instead of flat-contract-predicate so that the combinator can raise errors that use the combinator’s name in the error message.

> procedure (property/c accessor ctc [#:name name]) → flat-contract?
> accessor : (-> any/c any/c)
> ctc : flat-contract?
> name : any/c = (object-name accessor)

Constructs a flat contract that checks that the first-order property accessed by accessor satisfies ctc. The resulting contract is equivalent to

> (lambda (v) (ctc (accessor v)))

except that more information is included in error messages produced by violations of the contract. The name argument is used to describe the property being checked in error messages.

Examples:

> > (define/contract (sum-triple lst)
> (-> (and/c (listof number?)
> (property/c length (=/c 3)))
> number?)
> (+ (first lst) (second lst) (third lst)))
> > (sum-triple '(1 2 3))
> 6
> > (sum-triple '(1 2))
> sum-triple: contract violation
> expected: (=/c 3)
> given: 2
> in: the length of
> an and/c case of
> the 1st argument of
> (->
> (and/c
> (listof number?)
> (property/c length (=/c 3)))
> number?)
> contract from: (function sum-triple)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:2:0

Added in version 7.3.0.11 of package base.

> procedure (suggest/c c field message) → contract?
> c : contract?
> field : string?
> message : string?

Returns a contract that behaves like c, except that it adds an extra line to the error message on a contract violation.

The field and message strings are added following the guidelines in Error Message Conventions.

Examples:

> > (define allow-calls? #f)
> > (define/contract (f)
> (suggest/c (->* () #:pre allow-calls? any)
> "suggestion" "maybe you should set! allow-calls? to #t")
> 5)
> > (f)
> f: contract violation
> #:pre condition
> suggestion: maybe you should set! allow-calls? to #t
> in: (->* () #:pre ... any)
> contract from: (function f)
> blaming: top-level
> (assuming the contract is correct)
> at: eval:3:0

top contents ← prev up next →