7.6 Contract Utilities

► |  | Reference: Racket

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

▼ | 7 | Contracts

7.1 | Data-structure Contracts
7.2 | Function Contracts
7.3 | Lazy Data-structure Contracts
7.4 | Attaching Contracts to Values
7.5 | Building New Contract Combinators
7.6 | Contract Utilities

On this page:

contract?
flat-contract?
flat-contract-predicate
value-contract
has-contract?
contract-stronger?
contract-first-order-passes?
contract-name
contract-first-order
contract-projection
make-none/ c
current-blame-format
recursive-contract
opt/ c
define-opt/ c

top← prev up next →

#### 7.6`` Contract Utilities

( contract? v) → boolean?
v : any/c

Returns #t if its argument is a contract (i.e., constructed with one of the combinators described in this section or a value that can be used as a contract) and #f otherwise.

( flat-contract? v) → boolean?
v : any/c

Returns #t when its argument is a contract that can be checked immediately (unlike, say, a function contract).

For example, flat-contract constructs flat contracts from predicates, and symbols, booleans, numbers, and other ordinary Racket values (that are defined as contracts) are also flat contracts.

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

Extracts the predicate from a flat contract.

( value-contract v) → contract?
v : has-contract?

Returns the contract attached to v, if recorded. Otherwise it returns #f.

( has-contract? v) → boolean?
v : any/c

Returns #t if v is a value that has a recorded contract attached to it.

( contract-stronger? x y) → boolean?
x : contract?
y : contract?

Returns #t if the contract x accepts either fewer or the same number of values as y does.

This function is conservative, so it may return #f when x does, in fact, accept fewer values.

Examples:
> ( contract-stronger? integer? integer?)
#t
> ( contract-stronger? ( between/c 25 75) ( between/c 0 100))
#t
> ( contract-stronger? ( between/c 0 100) ( between/c 25 75))
#f
> ( contract-stronger? ( between/c -10 0) ( between/c 0 10))
#f

> ( contract-stronger? ( λ (x) ( and ( real? x) (<= x ( random 10))))
( λ (x) ( and ( real? x) (<= x (+ 100 ( random 10))))))

#f

( contract-first-order-passes? contract v) → boolean?
contract : contract?
v : any/c

Returns a boolean indicating if the first-order tests of contract pass for v.

If it returns #f, the contract is guaranteed not to hold for that value; if it returns #t, the contract may or may not hold. If the contract is a first-order contract, a result of #t guarantees that the contract holds.

( contract-name c) → any/c
c : contract?

Produces the name used to describe the contract in error messages.

( contract-first-order c) → (-> any/c boolean?)
c : contract?

Produces the first order test used by or/c to match values to higher order contracts.

( contract-projection c) → (-> blame? (-> any/c any/c))
c : contract?

Produces the projection defining a contract’s behavior on protected values.

( make-none/c sexp-name) → contract?
sexp-name : any/c

Makes a contract that accepts no values, and reports the name sexp-name when signaling a contract violation.

( current-blame-format) → (-> blame? any/c string? string?)
( current-blame-format proc) → void?
proc : (-> blame? any/c string? string?)

This is a parameter that is used when constructing a contract violation error. Its value is procedure that accepts three arguments:

- the blame object for the violation,

- the value that the contract applies to, and

- a message indicating the kind of violation.

The procedure then returns a string that is put into the contract error message. Note that the value is often already included in the message that indicates the violation.

Examples:

( define (show-blame-error blame value message)
( string-append
"Contract Violation!\n"
( format "Guilty Party: ~a\n" ( blame-positive blame))
( format "Innocent Party: ~a\n" ( blame-negative blame))
( format "Contracted Value Name: ~a\n" ( blame-value blame))
( format "Contract Location: ~s\n" ( blame-source blame))
( format "Contract Name: ~a\n" ( blame-contract blame))
( format "Offending Value: ~s\n" value)
( format "Offense: ~a\n" message)))

> [ current-blame-format show-blame-error]

> ( define/contract (f x)
(-> integer? integer?)
(/ x 2))

> (f 2)
1
> (f 1)
Contract Violation!
Guilty Party: (function f)
Innocent Party: top-level
Contracted Value Name: f
Contract Location: #(struct:srcloc eval 4 0 4 1)
Contract Name: (-> integer? integer?)
Offending Value: 1/2
Offense: expected <integer?>, given: 1/2
> (f 1/2)
Contract Violation!
Guilty Party: top-level
Innocent Party: (function f)
Contracted Value Name: f
Contract Location: #(struct:srcloc eval 4 0 4 1)
Contract Name: (-> integer? integer?)
Offending Value: 1/2
Offense: expected <integer?>, given: 1/2

( recursive-contract contract-expr)

Delays the evaluation of its argument until the contract is checked, making recursive contracts possible.

( opt/c contract-expr)

This optimizes its argument contract expression by traversing its syntax and, for known contract combinators, fuses them into a single contract combinator that avoids as much allocation overhad as possible. The result is a contract that should behave identically to its argument, except faster (due to the less allocation).

( define-opt/c (id id ...) expr)

This defines a recursive contract and simultaneously optimizes it. Semantically, it behaves just as if the -opt/c were not present, defining a function on contracts (except that the body expression must return a contract). But, it also optimizes that contract definition, avoiding extra allocation, much like opt/c does.

For example,

( define-contract-struct bt (val left right))
( define-opt/c (bst-between/c lo hi)
( or/c null?
(bt/c [val ( real-in lo hi)]
[left (val) (bst-between/c lo val)]
[right (val) (bst-between/c val hi)])))
( define bst/c (bst-between/c -inf.0 +inf.0))

defines the bst/c contract that checks the binary search tree invariant. Removing the -opt/c also makes a binary search tree contract, but one that is (approximately) 20 times slower.

top← prev up next →