#
Chapter 10
`contracts.ss`: Contracts

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

This section describes two classes of contracts: contracts for flat values (described in section 10.1) and contracts for functions (described in section 10.2).

In addition, this section describes two forms for establishing a contract on a value (described in section 10.3).

## 10.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-named-contract``` `type-name predicate``)` PROCEDURE

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.

`(flat-named-contract-type-name``` `flat-named-contract``)` PROCEDURE

Extracts the type name from a `flat-named-contract`.

`(flat-named-contract-predicate``` `flat-named-contract``)` PROCEDURE

Extracts the predicate from a `flat-named-contract`.

In addition, this library provides many helper functions for constructing contracts.

`(union``` `contract ...``)` PROCEDURE

`union` accepts any number of predicates and at most one function contract and returns a contract that corresponds to the union of them all.

`(and/f``` `predicate``)` PROCEDURE

`and/f` accepts a list of predicates and returns a predicate that is the conjunction of those predicates.

`(or/f``` `predicate ...``)` PROCEDURE

`or/f` accepts a list of predicates and returns a predicate that is the disjuction of those predicates.

`(>=/c``` `number``)` PROCEDURE

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

`(<=/c``` `number``)` PROCEDURE

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

`(>/c``` `number``)` PROCEDURE

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

`(</c``` `number``)` PROCEDURE

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

`natural-number?` FLAT-CONTRACT

`natural-number?` returns `#t` if the input is a natural number and `#f` otherwise.

`false?` FLAT-CONTRACT

`false?` returns true if the input is `#f` and `#t` otherwise.

`printable?` FLAT-CONTRACT

`printable?` returns `#t` for any value that can be written out and read back in.

`any?` FLAT-CONTRACT

`any?` always returns `#t`.

`(symbols``` `symbol ...``)` PROCEDURE

`symbols` accepts any number of symbols and returns a predicate that checks for those symbols.

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

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

`(implementation?/c``` `interface``)` PROCEDURE

`implementation?/c` accepts an interface and returns a predicate that checks if classes are implement the given interface.

`(subclass?/c``` `class``)` PROCEDURE

`subclass?/c` accepts a class and returns a predicate that checks if classes are subclasses of the original class.

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

`listof` accepts a flat contract and returns a predicate that checks for lists whose elements match the original predicate.

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

`vectorof` accepts a flat contract and returns a predicate that checks for vectors whose elements match the original predicate.

`(vector/p``` `flat-contract ...``)` FLAT-CONTRACT

`vector/p` accepts any number of flat contract and returns a predicate that checks for vectors. The number of elements in the vector must match the number of arguments supplied to `vector/p` and the elements of the vector must match the corresponding flat contract.

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

`box/p` accepts a flat contract and returns a flat contract that checks for boxes whose contents match `box/p`'s argument.

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

`cons/p` accepts two predicates and returns a predicate that checks for cons cells whose car and cdr correspond to `cons/p`'s two arguments.

`(list/p``` `flat-contract ...``)` PROCEDURE

`list/p` accepts an arbitrary number of arguments and returns a predicate that checks for lists whose length is the same as the number of arguments to `list/p` and whose elements match those arguments.

`mixin-contract` CONTRACT

`mixin-contract` is a contract that matches 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 ...``)` PROCEDURE

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

## 10.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 ...) expr (expr ...))
     | (->* (expr ...) (expr ...))
     | (->d expr ... expr)
     | (->*d (expr ...) expr)
     | (->*d (expr ...) expr expr)
     | (opt-> (expr ...) (expr ...) expr)
     | (opt->* (expr ...) (expr ...) (expr ...))

where `expr` is any Scheme 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 14.3 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.

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

`(->*``` `(expr ...) expr (expr ...)``)` 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.

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

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

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

## 10.3 Attaching Contracts to Scheme 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) ...))
      (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 `expr`.

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

Only uses of the contracted variable outside the module are checked.

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

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

## 10.4 Contract Utility

`contract?` PREDICATE

The procedure `contract?` returns `#t` if its argument was constructed with one of the arrow constructors described earlier in this section, or if its argument is a procedure of arity `1`.