8.3

## Contract Miscellanea

 (require contract-etc) package: contract-etc

### 1Combinators

This library is experimental; compatibility may not be maintained.

procedure

(dynamic->d make-contract)  contract?

make-contract :
 (-> (unconstrained-domain-> contract?) contract?)
This contract protects a procedure. It applies make-contract when the procedure is called with its arguments. The return value is expected to be a function contract that is then applied to the procedure, and the arguments are then reapplied to that protected procedure.

Examples:
 > (define increasing/c (dynamic->d (λ (x) (-> integer? (>/c x)))))

43

> (define/contract values* increasing/c values)
> (values* 42)

values*: broke its own contract

promised: a number strictly greater than 42

produced: 42

in: the range of

dynamic->d

contract from: (definition values*)

blaming: (definition values*)

(assuming the contract is correct)

at: eval:4:0

procedure

 (self/c make-contract [ #:chaperone? chaperone?]) → contract?
make-contract : (-> any/c contract?)
chaperone? : boolean? = #f
Constructs a contract where the contract itself depends on the value it’s protecting. When the contract is attached to a value, make-contract is applied to it and the resulting contract is then attached to that value.

Examples:
 > (define cdr-returns-car/c (self/c (λ (p) (match-define (cons x f) p) (cons/c any/c (-> x)))))
> (define/contract good-self cdr-returns-car/c (cons 1 (const 1)))
> ((cdr good-self))

1

> 1

1

> (define/contract bad-self cdr-returns-car/c (cons 1 (const 2)))

promised: 1

produced: 2

in: the range of

the cdr of

self/c

(assuming the contract is correct)

at: eval:10:0

syntax

(apply/c [contract-expr to-protect-expr maybe-swap] ...+)

maybe-swap =
| #:swap

syntax

(return/c [contract-expr to-protect-expr maybe-swap] ...+)

maybe-swap =
| #:swap
These contracts expect a procedure and sends a constant value through another contract when the procedure is applied or returns respectively. The #:swap option swaps the blame for violation of the contract.

Examples:
 > (define (apply-at-most-once/c) (define count 0) (define (incr n) (set! count (+ count n)) (<= count 1)) (apply/c [incr 1]))
> (define/contract f (apply-at-most-once/c) void)
> (f)
> (f)

f: contract violation

expected: incr

given: 1

in: apply/c

contract from: (definition f)

blaming: top-level

(assuming the contract is correct)

at: eval:13:0

procedure

 (class-object/c class-contract object-contract) → contract?
class-contract : contract?
object-contract : contract?
Creates a class contract that acts exactly like class-contract, except that instantiated objects are additionally constrained by object-contract.

Examples:
 > (define cat%/c (class-object/c (class/c [meow (->m integer? string?)]) (object/c [meow (->m positive? string?)])))
 > (define/contract cat% cat%/c (class object% (define/public (meow n) (string-join (map (const "meow") (range n)))) (super-new)))
> (define leo (new cat%))
> (send leo meow 1/2)

meow: contract violation

expected: integer?

given: 1/2

in: the 1st argument of

the meow method in

the class contract of

(class-object/c

(class/c (meow (->m integer? string?)))

(object/c (meow (->m positive? string?))))

contract from: (definition cat%)

contract on: cat%

blaming: top-level

(assuming the contract is correct)

at: eval:17:0

> (send leo meow -2)

meow: contract violation

expected: positive?

given: -2

in: the 1st argument of

the meow method in

the object contract of

(class-object/c

(class/c (meow (->m integer? string?)))

(object/c (meow (->m positive? string?))))

contract from: (definition cat%)

contract on: cat%

blaming: top-level

(assuming the contract is correct)

at: eval:17:0

> (send leo meow 4)

"meow meow meow meow"

### 2provide Forms

 syntax(exercise-out id ...)
Exercises the given options before providing.

Examples:
 > (module inner racket (require contract-etc racket/contract/option) (provide (exercise-out foo) (rename-out [foo unchecked-foo])) (define/contract (foo) (option/c (-> integer?)) "nan"))
> (require 'inner)
> (unchecked-foo)

"nan"

> (foo)

foo: broke its own contract

promised: integer?

produced: "nan"

in: the range of

the option of

(option/c (-> integer?))

contract from: (function foo)

blaming: (function foo)

(assuming the contract is correct)

at: eval:22:0

 syntax(waive-out id ...)
Similar to exercise-out, except it waives the given options before providing.

### 3Annotations

 (require contract-etc/annotate) package: contract-etc

Typically, programmers will only attach contracts at module or library boundaries with contract-out and not use contracts at the definition level with define/contract. This is because fine-grained contract boundaries cause major performance problems due to the overhead of repeated checking.

Contract annotations provide a convenient means of enabling and disabling internal contract checks as needed. For example, you may decide that for local testing you want to disable internal contract checks, but enable them during continuous integration testing.

 syntax(: id contract-expr)
Annotates the definition of id with a contract. The first-order part of the contract is checked immediately. For a flat contract, nothing else needs to happen. For a higher-order contract, an option of contract-expr is attached to id.

Where, and whether, that option is enabled depends on the environment variables present at run time.

• If CONTRACT_EXERCISE is set, then the option is enabled by default.

• If CONTRACT_EXERCISE_TEST is set, then the option is enabled by default only in the test submodule of the current file.

• If neither are set, then the option is disabled by default.

Examples:
> (: sub2 (-> number? number?))
> (define (sub2) 42)

sub2: broke its own contract

promised: a procedure that accepts 1 non-keyword argument

produced: #<procedure:sub2>

sub2 accepts: 0 arguments

in: (option/c

(-> number? number?)

#:tester

#<procedure:...arrow-val-first.rkt:1639:0>)

contract from: (function sub2)

blaming: (function sub2)

(assuming the contract is correct)

at: eval:27:0

> (: add2 (-> integer? integer?))
 > (define (add2 x) (+ x 2))

3.5

expected: integer?

given: 1.5

in: the 1st argument of

the option of

(option/c

(-> integer? integer?)

#:tester

#<procedure:...arrow-val-first.rkt:1639:0>)