#
Chapter 13
`contract.ss`: Contracts

To load: `(require (lib "contract.ss"))`

MzLib's `contract.ss` library defines new forms of expression that specify contracts and new forms of expression that attach contracts to values.

This section describes three classes of contracts: contracts for flat values (described in section 13.1), contracts for functions (described in section 13.2), and contracts for objects and classes (described in section 13.3).

In addition, this section describes how to establish a contract, that is, how to indicate that a particular contract should be enforced at a particular point in the program (in section 13.4).

## 13.1 Flat Contracts

A contract for a flat value can be a predicate that accepts the value and returns a boolean indicating if the contract holds.

`(flat-contract``` `predicate``)` FLAT-CONTRACT

Constructs a contract from `predicate`.

`(flat-named-contract``` `type-name predicate``)` FLAT-CONTRACT

For better error reporting, a flat contract can be constructed with `flat-named-contract`, a procedure that accepts two arguments. The first argument must be a string that describes the type that the predicate checks for. The second argument is the predicate itself.

`any/c` FLAT-CONTRACT

`any/c` is a flat contract that accepts any value.

If you are using this predicate as the result portion of a function contract, consider using `any` instead. It behaves the same, but in that one restrictive context has better memory performance.

`(union``` `contract``` `···``)` CONTRACT

`union` accepts any number of predicates and at most one function contract and returns a contract that corresponds to the union of them all. If all of the arguments are predicates or flat contracts, it returns a flat contract.

`(and/c``` `contract``` `···``)` CONTRACT

`and/c` accepts any number of contracts and returns a contract that checks that all of the argument contracts hold. If all of the arguments are flat contracts, `and/c` produces a flat contract.

`(not/c``` `flat-contract``)` FLAT-CONTRACT

`not/c` accepts a flat contracts (or a predicate which is implicitly converted to a flat contracts via `flat-contract`) and returns a flat contract that checks the reverse of the argument.

`(=/c``` `number``)` FLAT-CONTRACT

`=/c` accepts a number and returns a flat contract that requires the input to be a number and equal to the original input.

`(>=/c``` `number``)` FLAT-CONTRACT

`>=/c` accepts a number and returns a flat contract that requires the input to be a number and greater than or equal to the original input.

`(<=/c``` `number``)` FLAT-CONTRACT

`<=/c` accepts a number and returns a flat contract that requires the input to be a number and less than or equal to the original input.

`(>/c``` `number``)` FLAT-CONTRACT

`>/c` accepts a number and returns a flat contract that requires the input to be a number and greater than the original input.

`(</c``` `number``)` FLAT-CONTRACT

`</c` accepts a number and returns a flat contract that requires the input to be a number and less than the original input.

`(integer-in``` `number number``)` FLAT-CONTRACT

`integer-in` accepts two numbers and returns a flat contract that recognizes if integers between the two inputs, or equal to one of its inputs.

`(real-in``` `number number``)` FLAT-CONTRACT

`real-in` accepts two numbers and returns a flat contract that recognizes real numbers between the two inputs, or equal to one of its inputs.

`natural-number/c` FLAT-CONTRACT

`natural-number/c` is a contract that recognizes natural numbers (i.e., an integer that is either positive or zero).

`(string/len``` `number``)` FLAT-CONTRACT

`string/len` accepts a number and returns a flat contract that recognizes strings that have fewer than that number of characters.

`false/c` FLAT-CONTRACT

`false/c` is a flat contract that recognizes `#f`.

`printable/c` FLAT-CONTRACT

`printable/c` is a flat contract that recognizes values that can be written out and read back in with ``write`` and ``read``.

`(symbols``` `symbol``` `···`1`)` FLAT-CONTRACT

`symbols` accepts any number of symbols and returns a flat contract that recognizes for those symbols.

`(is-a?/c``` `class-or-interface``)` FLAT-CONTRACT

`is-a?/c` accepts a class or interface and returns a flat contract that recognizes if objects are subclasses of the class or implement the interface.

`(implementation?/c``` `interface``)` FLAT-CONTRACT

`implementation?/c` accepts an interface and returns a flat contract that recognizes if classes are implement the given interface.

`(subclass?/c``` `class``)` FLAT-CONTRACT

`subclass?/c` accepts a class and returns a flat-contract that recognizes classes that are subclasses of the original class.

`(listof``` `flat-contract``)` FLAT-CONTRACT

`listof` accepts a flat contract (or a predicate which is converted to a flat contract) and returns a flat contract that checks for lists whose elements match the original flat contract.

`(list-immutableof``` `contract``)` CONTRACT

`list-immutableof` accepts a contract (or a predicate which is converted to a flat contract) and returns a contract that checks for immutable lists whose elements match the original contract. In contrast to `listof`, `list-immutableof` accepts arbitrary contracts, not just flat contracts.

Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(vectorof``` `flat-contract``)` FLAT-CONTRACT

`vectorof` accepts a flat contract (or a predicate which is converted to a flat contract via `flat-contract`) and returns a predicate that checks for vectors whose elements match the original flat contract.

`(vector-immutableof``` `contract``)` CONTRACT

`vector-immutableof` accepts a contract (or a predicate which is converted to a flat contract) and returns a contract that checks for immutable lists whose elements match the original contract. In contrast to `vectorof`, `vector-immutableof` accepts arbitrary contracts, not just flat contracts.

Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(vector/c``` `flat-contract``` `···``)` FLAT-CONTRACT

`vector/c` accepts any number of flat contracts (or predicates which are converted to flat contracts via `flat-contract`) and returns a flat-contract that recognizes vectors. The number of elements in the vector must match the number of arguments supplied to `vector/c` and the elements of the vector must match the corresponding flat contracts.

`(vector-immutable/c``` `contract``` `···``)` CONTRACT

`vector-immutable/c` accepts any number of contracts (or predicates which are converted to flat contracts via `flat-contract`) and returns a contract that recognizes vectors. The number of elements in the vector must match the number of arguments supplied to `vector-immutable/c` and the elements of the vector must match the corresponding contracts.

In contrast to `vector/c`, `vector-immutable/c` accepts arbitrary contracts, not just flat contracts. Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(box/c``` `flat-contract``)` FLAT-CONTRACT

`box/c` accepts a flat contract (or predicate that is converted to a flat contract via `flat-contract`) and returns a flat contract that recognizes for boxes whose contents match `box/c`'s argument.

`(box-immutable/c``` `contract``)` CONTRACT

`box-immutable/c` one contracts (or a predicate that is converted to a flat contract via `flat-contract`) and returns a contract that recognizes boxes. The contents of the box must match the contract passed to to `box-immutable/c`.

In contrast to `box/c`, `box-immutable/c` accepts an arbitrary contract, not just a flat contract. Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(cons/c``` `flat-contract flat-contract``)` FLAT-CONTRACT

`cons/c` accepts two flat contracts (or predicates that are converted to flat contracts via `flat-contract`) and returns a flat contract that recognizes cons cells whose car and cdr correspond to `cons/c`'s two arguments.

`(cons-immutable/c``` `contract contract``)` CONTRACT

`cons-immutable/c` accepts two contracts (or predicates that are converted to flat contracts via `flat-contract`) and returns a contract that recognizes immutable cons cells whose car and cdr correspond to `cons-immutable/c`'s two arguments. In contrast to `cons/c`, `cons-immutable/c` accepts arbitrary contracts, not just flat contracts.

Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(list/c``` `flat-contract``` `···``)` FLAT-CONTRACT

`list/c` accepts an arbitrary number of flat contracts (or predicates that are converted to flat contracts via `flat-contract`) and returns a flat contract that recognizes for lists whose length is the same as the number of arguments to `list/c` and whose elements match those arguments.

`(list-immutable/c``` `contract``` `···``)` CONTRACT

`list-immutable/c` accepts an arbitrary number of contracts (or predicates that are converted to flat contracts via `flat-contract`) and returns a contract that recognizes for lists whose length is the same as the number of arguments to `list-immutable/c` and whose elements match those contracts.

In contrast to `list/c`, `list-immutable/c` accepts arbitrary contracts, not just flat contracts. Beware, however, that when a value is applied to this contract, the result will not be ``eq?`` to the input.

`(syntax/c``` `flat-contract``)` FLAT-CONTRACT

`syntax/c` accepts a flat contract and produces a flat contract that recognizes syntax objects whose contents match the argument to `syntax/c`.

`(struct/c``` `struct-name flat-contract ...``)` FLAT-CONTRACT

`struct/c` accepts a struct name and as many flat contracts as there are fields in the named struct. It returns a contract that accepts instances of that struct whose fields match the given contracts.

`(`flat-rec-contract` `name flat-contract `···``)` SYNTAX

Each `flat-rec-contract` form constructs a flat recursive contract. The first argument is the name of the contract and the following arguments are flat contract expressions that may refer to `name`.

As an example, this 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 an `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.

`(`flat-murec-contract` `([name flat-contract `···`] `···`) body `···``)` SYNTAX

The `flat-murec-contract` form is a generalization of `flat-rec-contracts` for defining several mutually recursive flat contracts simultaneously.

Each of the names is visible in the entire `flat-murec-contract` and the result of the final body expression is the result of the entire form.

Note that if the contract is applied to a circular value, contract checking will not terminate.

`(anaphoric-contracts``)` CONTRACT CONTRACT

`(anaphoric-contracts``` `'equal``)` CONTRACT CONTRACT

Returns two linked anaphoric contracts. The first allows all values, and the second only allows values that the first has previously seen.

## 13.2 Function Contracts

->

This section describes the contract constructors for function contracts. This is their shape:

    contract-expr ::==
     | (case-> arrow-contract-expr ···)
     | arrow-contract-expr

    arrow-contract-expr ::==
     | (-> expr ··· expr)
     | (-> expr ··· any)
     | (-> expr ··· (values expr ···))

     | (->* (expr ···) (expr ···))
     | (->* (expr ···) any)
     | (->* (expr ···) expr (expr ···))
     | (->* (expr ···) expr any)

     | (->d expr ··· expr)
     | (->d* (expr ···) expr)
     | (->d* (expr ···) expr expr)

     | (->r ((id expr) ···) expr)
     | (->r ((id expr) ···) any)
     | (->r ((id expr) ···) (values (id expr) ···))
     | (->r ((id expr) ···) id expr expr)
     | (->r ((id expr) ···) id expr any)
     | (->r ((id expr) ···) id expr (values (id expr) ···))

     | (->pp ((id expr) ···) pre-expr expr res-id post-expr)
     | (->pp ((id expr) ···) pre-expr any)
     | (->pp ((id expr) ···) pre-expr (values (id expr) ···) post-expr)

     | (->pp-rest ((id expr) ···) id expr pre-expr expr res-id post-expr)
     | (->pp-rest ((id expr) ···) id expr pre-expr any)
     | (->pp-rest ((id expr) ···) id expr pre-expr (values (id expr) ···) post-expr)

     | (opt-> (expr ···) (expr ···) expr)
     | (opt->* (expr ···) (expr ···) any)
     | (opt->* (expr ···) (expr ···) (expr ···))

where `expr` is any expression.

`(`->` `expr `···``)` SYNTAX

`(`->` `expr `···`any`)` SYNTAX

The `->` contract is for functions that accept a fixed number of arguments and return a single result. The last argument to `->` is the contract on the result of the function and the other arguments are the contracts on the arguments to the function. Each of the arguments to `->` must be another contract expression or a predicate. For example, this expression:

    (integer? boolean? . -> . integer?)

is a contract on functions of two arguments. The first must be an integer and the second a boolean and the function must return an integer. (This example uses MzScheme's infix notation so that the `->` appears in a suggestive place; see section 11.2.4 in PLT MzScheme: Language Manual).

If `any` is used as the last argument to `->`, no contract checking is performed on the result of the function, and tail-recursion is preserved. Except for the memory performance, this is the same as using `any/c` in the result.

The final case of `->` expressions treats ``values`` as a local keyword - that is, you may not return multiple values to this position, instead if the word ``values`` syntactically appears in the in the last argument to `->` the function is treated as a multiple value return (this is a shorthand for the two argument variant on `->*`).

`(`->*` `(expr `···`) (expr `···`)`)` SYNTAX

`(`->*` `(expr `···`) any`)` SYNTAX

`(`->*` `(expr `···`) expr (expr `···`)`)` SYNTAX

`(`->*` `(expr `···`) expr any`)` SYNTAX

The `->*` expression is for functions that return multiple results and/or have rest arguments. If two arguments are supplied, the first is the contracts on the arguments to the function and the second is the contract on the results of the function. If three arguments are supplied, the first argument contains the contracts on the arguments to the function (excluding the rest argument), the second contains the contract on the rest argument to the function and the final argument is the contracts on the results of the function. The final argument can be `any` which, like `->` means that no contract is enforced on the result of the function and tail-recursion is preserved.

`(`->d` `expr `···``)` SYNTAX

`(`->d*` `(expr `···`) expr)`)` SYNTAX

`(`->d*` `(expr `···`) expr expr`)` SYNTAX

The `->d` and `->d*` contract constructors are like their d-less counterparts, except that the result portion is a function that accepts the original arguments to the function and returns the range contracts. The range contract function for `->d*` must return multiple values: one for each result of the original function. As an example, this is the contract for ``sqrt``:

    (number?
     . ->d .
     (lambda (in)
       (lambda (out)
         (and (number? out)
              (abs (- (* out out) in) 0.01)))))

It says that the input must be a number and that the difference between the square of the result and the original number is less than `0.01`.

`(`->r` `([id expr] `···`) expr`)` SYNTAX

The `->r` contract allows you to build a contract where the arguments to a function may all depend on each other and the result of the function may depend on all of the arguments.

Each of the `id`s names one of the actual arguments to the function with the contract. Each of the names is available to all of the other contracts. For example, to define a function that accepts three arguments where the second argument and the result must both be between the first, you might write:

    (->r ([x number?] [y (and/c (>=/c x) (<=/c z))] [z number?])
         (and/c number? (>=/c x) (<=/c z)))

`(`->r` `([id expr] `···`) any`)` SYNTAX

This variation on `->r` does not check anything about the result of the function, which preserves tail recursion.

`(`->r` `([id expr] `···`) (values [id expr] ...)`)` SYNTAX

This variation on `->r` allows multiple value return values. The `id`s for the domain are bound in all of the `expr`s, but the `id`s for the range (the ones inside ``values``) are only bound in the `exprs` inside the ``values``.

As an example, this contract:

    (->r () (values [x number?]
                    [y (and/c (>=/c x) (<=/c z))]
                    [z number?]))

matches functions that accept no arguments and that return three numeric values that are in ascending order.

`(`->r` `([id expr] `···`) id expr expr`)` SYNTAX

`(`->r` `([id expr] `···`) id expr any`)` SYNTAX

`(`->r` `([id expr] `···`) id expr (values [id expr] ...)`)` SYNTAX

These three forms of the `->r` contract are just like the previous ones, except that the functions they matches must accept arbitrarily many arguments. The extra `id` and the `expr` just following it specify the contracts on the extra arguments. The value of `id` will alway be a list (of the extra arguments).

`(`->pp` `([id expr] `···`) pre-expr expr res-id post-expr`)` SYNTAX

`(`->pp` `([id expr] `···`) pre-expr any`)` SYNTAX

`(`->pp` `([id expr] `···`) pre-expr (values [id expr] ...) post-expr`)` SYNTAX

`(`->pp-rest` `([id expr] `···`) id expr pre-expr expr res-id post-expr`)` SYNTAX

`(`->pp-rest` `([id expr] `···`) id expr pre-expr any`)` SYNTAX

`(`->pp-rest` `([id expr] `···`) id expr pre-expr (values [id expr] ...) post-expr`)` SYNTAX

These six shapes of `->pp` match up to the six shapes of `->r` forms explained above, with the addition that the extra pre- and post-condition expressions must not evaluate to `#f`.

If the pre-condition evaluates to `#f`, the caller is blamed and if the post-condition expression evaluates to `#f` the function itself is blamed.

The argument variables are bound in the `pre-expr` and the `post-expr` and the variables in the ``values`` result clauses are bound in the `post-expr`.

Additionally, the variable `res-id` is bound to the result in the first `->pp` case and in the first `->pp-rest` case.

`(`case->` `arrow-contract-expr `···``)` CONTRACT-CASE->

The `case->` expression constructs a contract for case-lambda function. It's arguments must all be function contracts, built by one of `->`, `->d`, `->*`, or `->d*`.

`(`opt->` `(req-contracts `···`) (opt-contracts `···`) res-contract)`)` SYNTAX

`(`opt->*` `(req-contracts `···`) (opt-contracts `···`) (res-contracts `···`)`)` SYNTAX

`(`opt->*` `(req-contracts `···`) (opt-contracts `···`) any`)` SYNTAX

The `opt->` expression constructs a contract for an `opt-lambda` function. The first arguments are the required parameters, the second arguments are the optional parameters and the final argument is the result. The `req-contracts` expressions, the `opt-contracts` expressions, and the `res-contract` expressions can be any expression that evaluates to a contract value.

Each `opt->` expression expands into `case->`.

The `opt->*` expression constructs a contract for an `opt-lambda` function. The only difference between `opt->` and `opt->*` is that multiple return values are permitted with `opt->*` and they are specified in the last clause of an `opt->*` expression. A result of `any` means any value or any number of values may be returned, and the contract does not inhibit tail-recursion.

## 13.3 Object and Class Contracts

This section describes contracts on classes and objects. Here is the basic shape of an object contract:

    contract-expr ::== ···
     | (object-contract meth/field-spec ···)

    meth/field-spec ::==
       (meth-name meth-contract)
     | (field field-name contract-expr)

    meth-contract ::==
       (opt-> (required-contract-expr ···)
              (optional-contract-expr ···)
              any)
       (opt-> (required-contract-expr ···)
              (optional-contract-expr ···)
              result-contract-expr)
     | (opt->* (required-contract-expr ···)
               (optional-contract-expr ···)
               (result-contract-expr ···))
     | (case-> meth-arrow-contract ···)
     | meth-arrow-contract

    meth-arrow-contract ::==
       (-> dom-contract-expr ··· rng-contract-expr)
     | (-> dom-contract-expr ··· (values rng-contract-expr ···))
     | (->* (dom-contract-expr ···) (rng-contract-expr ···))
     | (->* (dom-contract-expr ···) rest-arg-contract-expr (rng-contract-expr ···))
     | (->d dom-contract-expr ··· rng-contract-proc-expr)
     | (->d* (dom-contract-expr ···) rng-contract-proc-expr)
     | (->d* (dom-contract-expr ···) rest-contract-expr rng-contract-proc-expr)
     | (->r ((id expr) ···) expr)
     | (->r ((id expr) ···) id expr expr)

Each of the contracts for methods has the same semantics as the corresponding function contract (discussed above), but the syntax of the method contract must be written directly in the body of the object-contract (much like the way that methods in class definitions use the same syntax as regular function definitions, but cannot be arbitrary procedures).

`mixin-contract` CONTRACT

`mixin-contract` is a contract that recognizes mixins. It is a function contract. It guarantees that the input to the function is a class and the result of the function is a subclass of the input.

`(make-mixin-contract``` `class-or-interface``` `···``)` CONTRACT

`make-mixin-contract` is a function that constructs mixins contracts. It accepts any number of classes and interfaces and returns a function contract. The function contract guarantees that the input to the function implements the interfaces and is derived from the classes and that the result of the function is a subclass of the input.

## 13.4 Attaching Contracts to Values

There are three special forms that attach contract specification to values: `provide/contract`, `define/contract`, and `contract`.

`(`provide/contract` `p/c-item `···``)` SYNTAX

    p/c-item is one of
      (struct identifier ((identifier contract-expr) ···))
      (struct (identifier identifier) ((identifier contract-expr) ···))
      (rename id id contract-expr)
      (id contract-expr)

A `provide/contract` form can only appear at the top-level of a module (see section 5 in PLT MzScheme: Language Manual). As with `provide`, each identifier is provided from the module. In addition, clients of the module must live up to the contract specified by `contract-expr`.

The `provide/contract` form treats modules as units of blame. The module that defines the provided variable is expected to meet the positive (co-variant) positions of the contract. Each module that imports the provided variable must obey the negative (contra-variant) positions of the contract.

Only uses of the contracted variable outside the module are checked. Inside the module, no contract checking occurs.

The `rename` form of a `provide/contract` exports the first variable (the internal name) with the name specified by the second variable (the external name).

The `struct` form of a `provide/contract` clause provides a structure definition. Each field has a contract that dictates the contents of the fields.

If the struct has a parent, the second `struct` form (above) must be used, with the first name referring to the struct itself and the second name referring to the parent struct. Unlike `define-struct`, however, all of the fields (and their contracts) must be listed. The contract on the fields that the sub-struct shares with its parent are only used in the contract for the sub-struct's maker, and the selector or mutators for the super-struct are not provided.

Note that the struct definition must come before the provide clause in the module's body.

`(`define/contract` `id contract-expr init-value-expr`)` SYNTAX

The `define/contract` form attaches the contract `contract-expr` to `init-value-expr` and binds that to `id`.

The `define/contract` form treats individual definitions as units of blame. The definition itself is responsible for positive (co-variant) positions of the contract and each reference to `id` (including those in the initial value expression) must meet the negative positions of the contract.

Error messages with `define/contract` are not as clear as those provided by `provide/contract` because `define/contract` cannot detect the name of the definition where the reference to the defined variable occurs. Instead, it uses the source location of the reference to the variable as the name of that definition.

`(`contract` `contract-expr to-protect-expr positive-blame negative-blame`)` SYNTAX

`(`contract` `contract-expr to-protect-expr positive-blame negative-blame contract-source`)` SYNTAX

The `contract` special form is the primitive mechanism for attaching a contract to a value. Its purpose is as a target for the expansion of some higher-level contract specifying form.

The `contract` form has this shape:

    (contract expr to-protect-expr positive-blame negative-blame contract-source)

The `contract` expression adds the contract specified by the first argument to the value in the second argument. The result of a `contract` expression is the result of the `to-protect-expr` expression, but with the contract specified by `contract-expr` enforced on `to-protect-expr`. The expressions `positive-blame` and `negative-blame` must be symbols indicating how to assign blame for positive and negative positions of the contract specified by `contract-expr`. Finally, `contract-source`, if specified, indicates where the contract was assumed. It must be a syntax object specifying the source location of the location where the contract was assumed. If the syntax object wraps a symbol, the symbol is used as the name of the primitive whose contract was assumed. If absent, it defaults to the source location of the `contract` expression.

## 13.5 Contract Utility

`contract?` PREDICATE

The procedure `contract?` returns `#t` if its argument is a contract (ie, constructed with one of the combinators described in this section).

`flat-contract?` PREDICATE

This predicate returns true when its argument is a contract that has been constructed with `flat-contract` (and thus is essentially just a predicate).

`(flat-contract-predicate``` `value``)` SELECTOR

This function extracts the predicate from a flat contract.