1 Language Model
2 Syntactic Forms
3 Datatypes
4 Structures
5 Classes and Objects
6 Units
7 Contracts
8 Pattern Matching
9 Control Flow
10 Concurrency
11 Macros
12 Input and Output
13 Reflection and Security
14 Operating System
15 Memory Management
16 Running PLT Scheme
Bibliography
Index
On this page:
provide/ contract
define/ contract
contract
Version: 4.0.2

 

7.4 Attaching Contracts to Values

(provide/contract p/c-item ...)

 

p/c-item

 

=

 

(struct id ((id contract-expr) ...))

 

 

|

 

(struct (id identifier) ((id contract-expr) ...))

 

 

|

 

(rename orig-id id contract-expr)

 

 

|

 

(id contract-expr)

Can only appear at the top-level of a module. As with provide, each id is provided from the module. In addition, clients of the module must live up to the contract specified by contract-expr for each export.

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, and each field has a contract that dictates the contents of the fields. The struct definition must come before the provide clause in the module’s body. 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.

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

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-expr negative-blame-expr)

(contract contract-expr to-protect-expr

          positive-blame-expr negative-blame-expr

          contract-source-expr)

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

The contract expression adds the contract specified by contract-expr to the value produced by to-protect-expr. 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 values of positive-blame-expr and negative-blame-expr must be symbols indicating how to assign blame for positive and negative positions of the contract specified by contract-expr.

If specified, contract-source-expr, indicates where the contract was assumed. Its value 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.