#
Chapter 13
`contract.ss`: Contracts

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 establishing a contract on a value (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``)` F L A T-C O N T R A C T

Constructs a contract from `predicate`.

`(flat-named-contract``` `type-name predicate``)` F L A T-C O N T R A C T

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?` F L A T-C O N T R A C T

`any?` 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``` `···``)` C O N T R A C T

`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``` `···``)` C O N T R A C T

`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/f``` `flat-contract``)` F L A T-C O N T R A C T

`not/f` 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``)` F L A T-C O N T R A C T

`>=/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``)` F L A T-C O N T R A C T

`<=/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``)` F L A T-C O N T R A C T

`>/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``)` F L A T-C O N T R A C T

`</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``)` F L A T-C O N T R A C T

`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``)` F L A T-C O N T R A C T

`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?` F L A T-C O N T R A C T

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

`(string/len``` `number``)` F L A T-C O N T R A C T

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

`false?` F L A T-C O N T R A C T

`false?` is a flat contract that recognizes `#f`.

`printable?` F L A T-C O N T R A C T

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

`(symbols``` `symbol``` `···`1`)` F L A T-C O N T R A C T

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

`(is-a?/c``` `class-or-interface``)` F L A T-C O N T R A C T

`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``)` F L A T-C O N T R A C T

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

`(subclass?/c``` `class``)` F L A T-C O N T R A C T

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

`(listof``` `flat-contract``)` F L A T-C O N T R A C T

`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``)` C O N T R A C T

`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``)` F L A T-C O N T R A C T

`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``)` C O N T R A C T

`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/p``` `flat-contract``` `···``)` F L A T-C O N T R A C T

`vector/p` 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/p` and the elements of the vector must match the corresponding flat contracts.

`(vector-immutable/c``` `contract``` `···``)` C O N T R A C T

`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/p`, `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/p``` `flat-contract``)` F L A T-C O N T R A C T

`box/p` 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/p`'s argument.

`(box-immutable/c``` `contract``)` C O N T R A C T

`box-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 `box-immutable/c` and the elements of the vector must match the corresponding contracts.

In contrast to `box/p`, `box-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.

`(cons/p``` `flat-contract flat-contract``)` F L A T-C O N T R A C T

`cons/p` 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/p`'s two arguments.

`(cons-immutable/c``` `contract contract``)` C O N T R A C T

`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/p`, `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/p``` `flat-contract``` `···``)` F L A T-C O N T R A C T

`list/p` 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/p` and whose elements match those arguments.

`(list-immutable/c``` `flat-contract``` `···``)` C O N T R A C T

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

In contrast to `list/p`, `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.

`(`flat-rec-contract` `name flat-contract `···``)` S Y N T A X

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.

`(`flat-murec-contract` `([name flat-contract `···`] `···`) body `···``)` S Y N T A X

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.

`(anaphoric-contracts``)` C O N T R A C T C O N T R A C T

`(anaphoric-contracts``` `'equal``)` C O N T R A C T C O N T R A C T

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) ···))

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

where `expr` is any expression.

`(`->` `expr `···``)` S Y N T A X

`(`->` `expr `···`any`)` S Y N T A X

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. Except for the memory performance, this is the same as using `any?` 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 `···`)`)` S Y N T A X

`(`->*` `(expr `···`) any`)` S Y N T A X

`(`->*` `(expr `···`) expr (expr `···`)`)` S Y N T A X

`(`->*` `(expr `···`) expr any`)` S Y N T A X

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 `···``)` S Y N T A X

`(`->d*` `(expr `···`) expr)`)` S Y N T A X

`(`->d*` `(expr `···`) expr expr`)` S Y N T A X

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`)` S Y N T A X

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`)` S Y N T A X

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

`(`->r` `([id expr] `···`) (values [id expr] ...)`)` S Y N T A X

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 numberic values that are in ascending order.

`(`->r` `([id expr] `···`) id expr expr`)` S Y N T A X

`(`->r` `([id expr] `···`) id expr any`)` S Y N T A X

`(`->r` `([id expr] `···`) id expr (values [id expr] ...)`)` S Y N T A X

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

`(`case->` `arrow-contract-expr `···``)` C O N T R A C T-C A S E->

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)`)` S Y N T A X

`(`opt->*` `(req-contracts `···`) (opt-contracts `···`) (res-contracts `···`)`)` S Y N T A X

`(`opt->*` `(req-contracts `···`) (opt-contracts `···`) any`)` S Y N T A X

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` C O N T R A C T

`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``` `···``)` C O N T R A C T

`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 `···``)` S Y N T A X

    p/c-item is one of
      (struct 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 `expr`.

The `provide/contract` form treats modules as units of blame. The module that defines the provided variable is expected to meet the (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.

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.

`(`define/contract` `id contract-expr init-value-expr`)` S Y N T A X

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`)` S Y N T A X

`(`contract` `contract-expr to-protect-expr positive-blame negative-blame contract-source`)` S Y N T A X

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?` P R E D I C A T E

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

`flat-contract?` P R E D I C A T E

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``)` S E L E C T O R

This function extracts the predicate from a flat contract.