► |  | Reference: PLT Scheme

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 | Unsafe Operations
17 | Running PLT Scheme
| Bibliography
| Index

▼ | 7 | Contracts

7.1 | Data-structure Contracts
7.2 | Function Contracts
7.3 | Lazy Data-structure Contracts
7.4 | Attaching Contracts to Values
7.5 | Building New Contract Combinators
7.6 | Contract Utilities

On this page:

provide/ contract
with-contract
define/ contract
define-struct/ contract
contract

top← prev up next →

#### 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)
|  | | |  | #:∃ exists-variables
|  | | |  | #:exists exists-variables
exists-variables |  | = |  | identifier
|  | | |  | (identifier ...)

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.

The #:∃ and #:exists clauses define new abstract contracts. The variables are bound in the remainder of the provide/contract expression to new contracts that hide the values they accept and ensure that the exported functions are treated parametrically.

(with-contract blame-id (wc-export ...) free-var-list body ...+)

wc-export |  | = |  | (id contract-expr)

free-var-list

=

|  | | |  | #:freevars ([id contract-expr] ...)
|  | | |  | #:freevar id contract-expr

Generates a local contract boundary. The contract-expr form cannot appear in expression position. The body of the form allows definition/expression interleaving like a module body. All names defined within the with-contract form are visible externally, but those names listed in the wc-export list are protected with the corresponding contract.

The blame-id is used for the positive positions of contracts paired with exported ids. Contracts broken within the with-contract body will use the blame-id for their negative position.

If a free-var-list is given, then any uses of the free variables inside the body will be protected with contracts that blame the context of the with-contract form for the positive positions and the with-contract form for the negative ones.

(define/contract id contract-expr free-var-list init-value-expr)
(define/contract (head args) contract-expr free-var-list body ...+)

Works like define, except that the contract contract-expr is attached to the bound value. For the definition of head and args, see define. For the definition of free-var-list, see with-contract.

The define/contract form treats the individual definition as a contract region. The definition itself is responsible for positive (co-variant) positions of the contract and references to id outside of the definition must meet the negative positions of the contract. Since the contract boundary is between the definition and the surrounding context, references to id inside the define/contract form are not checked.

If a free-var-list is given, then any uses of the free variables inside the body will be protected with contracts that blame the context of the define/contract form for the positive positions and the define/contract form for the negative ones.

(define-struct/contract struct-id ([field contract-expr] ...)
struct-option ...)

(define-struct/contract (struct-id super-struct-id)
([field contract-expr] ...)
struct-option ...)

Works like define-struct, except that the arguments to the constructor, accessors, and mutators are protected by contracts. For the definitions of field and struct-option, see define-struct.

The define-struct/contract form only allows a subset of the struct-option keywords: #:mutable, #:transparent, #:auto-value, #:omit-define-syntaxes, #:property and #:omit-define-values.

Examples:
> (define-struct/contract fish ([color number?]))
> (make-fish 5)
#<fish>
> (make-fish #f)
top-level broke the contract (-> number? symbol? any) on
make-fish; expected <number?>, given: #f
> (define-struct/contract (salmon fish) ([ocean symbol?]))
> (make-salmon 5 'atlantic)
#<salmon>
> (make-salmon 5 #f)

top-level broke the contract
(-> any/c symbol? symbol?

any)
on make-salmon; expected <symbol?>, given: #f

> (make-salmon #f 'pacific)
top-level broke the contract (-> number? symbol? any) on
make-fish; expected <number?>, given: #f

(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-info)

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-info, indicates where the contract was assumed. Its value must be a either:

- a list of two elements: srcloc struct and either a string or #f. The srcloc struct indicates where the contract was assumed. Its source field should be a syntax object, and module-path-index-resolve is called on it to extract the path of syntax object.

  If the second element of the list is not #f, it is used as the name of the identifier whose contract was assumed.

- 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 with no identifying name.

The second form above is not recommended, because mzscheme strips source location information from compiled files.

top← prev up next →