On this page:
make-none/ c
opt/ c
define-opt/ c

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.

Extracts the predicate from a flat 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-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.

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.

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.


  (define (show-blame-error blame value message)
     "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)


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