7.1Contracts and Boundaries

Like a contract between two business partners, a software
contract is an agreement between two parties. The agreement
specifies obligations and guarantees for each “product”
(or value) that is handed from one party to the other.

A contract thus establishes a boundary between the two parties. Whenever a
value crosses this boundary, the contract monitoring system performs contract
checks, making sure the partners abide by the established contract.

In this spirit, Racket encourages contracts mainly at module
boundaries. Specifically, programmers may attach contracts to
provide clauses and thus impose constraints and promises on the use
of exported values. For example, the export specification

promises to all clients of the above module that the value of amount will
always be a positive number. The contract system monitors
the module’s obligation carefully. Every time a client
refers to amount, the monitor checks that the value
of amount is indeed a positive number.

The contracts library is built into the Racket language, but
if you wish to use racket/base, you can explicitly
require the contracts library like this:

In this case, the monitoring system will apply
positive? to a symbol, but positive?
reports an error, because its domain is only numbers. To
make the contract capture our intentions for all Racket
values, we can ensure that the value is both a number and is
positive, combining the two contracts with and/c:

7.1.2Experimenting with Contracts and Modules

All of the contracts and modules in this chapter (excluding those just
following) are written using the standard #lang syntax for
describing modules. Since modules serve as the boundary between
parties in a contract, examples involve multiple modules.

To experiment with multiple modules within a single module or within
DrRacket’s definitions area, use
Racket’s submodules. For example, try the example earlier in
this section like this:

Each of the modules and their contracts are wrapped in parentheses
with the module+ keyword at the front. The first form after
module is the name of the module to be used in a subsequent
require statement (where each reference through a
require prefixes the name with "..").

7.1.3Experimenting with Nested Contract Boundaries

In many cases, it makes sense to attach contracts at module boundaries.
It is often convenient, however, to be able to use contracts at
a finer granularity than modules. The define/contract
form enables this kind of use:

In this example, the define/contract form establishes a contract
boundary between the definition of amount and its surrounding
context. In other words, the two parties here are the definition and
the module that contains it.