On this page:
obstinacy?
impersonator-obstinacy
impersonator-obstinacy?
chaperone-obstinacy
chaperone-obstinacy?
flat-obstinacy
flat-obstinacy?
obstinacy-contract/  c
obstinacy-get-make-contract
obstinacy-get-coerce-contract-for-id
value-name-for-contract
let/  c
fix/  c
by-own-method/  c
equal/  c
flat-contract-accepting/  c

2 Utilities for Contracts

 (require lathe-comforts/contract)
  package: lathe-comforts-lib

procedure

(obstinacy? v)  boolean?

  v : any/c
Returns whether the given value is a contract obstinacy, which is an enumeration that distinguishes between impersonator contracts, chaperone contracts, and flat contracts.

Contract obstinacy can be thought of as a scale with two ends. Impersonator contracts are the most obstinate since they can go to any length to impose behavior on the values that pass through, while flat contracts are the most reticent since they don’t pass any more judgment on a value after they’ve ferried it through.

By default, Racket contracts are usually as obstinate as can be; contract? refers generally to impersonator contracts. Only certain contracts exercise reticence.

Struct-like operations which construct and deconstruct a contract obstinacy that represents impersonator contracts.

Every two impersonator-obstinacy values are equal?.

syntax

chaperone-obstinacy

syntax

(chaperone-obstinacy)

match expander

(chaperone-obstinacy)

procedure

(chaperone-obstinacy? v)  boolean?

  v : any/c
Struct-like operations which construct and deconstruct a contract obstinacy that represents chaperone contracts.

Every two chaperone-obstinacy values are equal?.

syntax

flat-obstinacy

syntax

(flat-obstinacy)

match expander

(flat-obstinacy)

procedure

(flat-obstinacy? v)  boolean?

  v : any/c
Struct-like operations which construct and deconstruct a contract obstinacy that represents flat contracts.

Every two flat-obstinacy values are equal?.

procedure

(obstinacy-contract/c ob)  flat-contract?

  ob : obstinacy?
Returns a flat contract that recognizes contracts that are at least as reticent as the given contract obstinacy. For instance, (obstinacy-contract/c (chaperone-obstinacy)) returns a flat contract that’s equivalent to (perhaps even identical to) chaperone-contract?.

procedure

(obstinacy-get-make-contract ob)  procedure?

  ob : obstinacy?
Given a contract obstinacy, returns the analogous make-contract, make-chaperone-contract, or make-flat-contract procedure.

procedure

(obstinacy-get-coerce-contract-for-id ob 
  id) 
  (-> any/c (obstinacy-contract/c ob))
  ob : obstinacy?
  id : symbol?
Returns a procedure that takes a single value and coerces it to a contract that’s at least as reticent as the given contract obstinacy. This is done using coerce-contract, coerce-chaperone-contract, or coerce-flat-contract.

If the value to be converted is not one of the coercible values, the coercion procedure signals an error with id in its error message.

procedure

(value-name-for-contract v)  any/c

  v : any/c
Gets the contract-name of the given value if it’s a contract, and merely returns the value otherwise. This can be handy when defining a new contract where the contract-name may embed arbitrary values, but embedded contracts in particular should be easy to read.

syntax

(let/c [var-id val-expr] ... body-expr)

 
  body-expr : contract?
Evaluates each val-expr, evaluates the body-expr with those values in scope under respective var-id variables, and renames the resulting contract to `(let/c [var-id ,(value-name-for-contract val)] ... ,body-expr), where each val is the result of a val-expr.

This can come in handy when composiing relatively large contracts that use the same value in multiple places. It keeps the name more concise than it usually would be.

syntax

(fix/c self-id options ... contract-expr)

(fix/c (self-id [arg-id arg-expr] ...) options ... contract-expr)
 
  contract-expr : contract?
A fixed-point syntax for contracts. Returns the result of running contract-expr with a certain contract or contract-returning function in scope as self-id, and with each given arg-expr’s result in scope as the corresponding arg-id.

In the unparenthesized case, self-id is bound to a contract. The contract functionality of self-id should be used only after contract-expr has returned a contract, and it behaves just like that contract.

In the parenthesized case, self-id is bound to a contract-returning function that takes one argument for each arg-id. The contract functionality of the result of self-id should be used only after contract-expr has returned a contract, and it works by evaluating contract-expr again with arg-id bound to each function argument.

In both cases, the contract obtained from self-id is delayed so that it can be used without causing an infinite loop. This functionality is based on recursive-contract, and the given options supply the optional arguments of the recursive-contract operation.

Example:
> (fix/c simple-s-expression/c
    (or/c symbol? (listof simple-s-expression/c)))

#<contract: (fix/c simple-s-expression/c (or/c symbol? (listof simple-s-expression/c)))>

syntax

(by-own-method/c maybe-obstinacy pat body-expr)

 
maybe-obstinacy = 
  | #:obstinacy obstinacy-expr
 
  obstinacy-expr : obstinacy?
  body-expr : (obstinacy-contract/c obstinacy-expr)
A syntax for contracts that depend on the value they apply to. Returns a contract that tries to match the value against the match pattern pat, and if successful, executes the body-expr (with all the bound variables from pat in scope) and behaves according to that contract. If the match is not successful, then the value is not considered to meet this contract.

A contract obstinacy may be given as obstinacy-expr, which defaults to (impersonator-obstinacy). The overall result is a contract of that contract obsinacy (e.g. a chaperone contract if using (chaperone-obstinacy), or any contract at all if using (impersonator-obstinacy)). The result of body-expr must be a contract of that contract obstinacy as well.

The name of the returned contract includes pat and body-expr verbatim. If they contain references to variables defined elsewhere, let/c may be useful to ensure those variable bindings are apparent in the overall contract name.

procedure

(equal/c example)  flat-contract?

  example : any/c
Returns a contract that recognizes a value if the given value is equal? to it.

procedure

(flat-contract-accepting/c v)  flat-contract?

  v : any/c
Returns a flat contract that recognizes any flat contract that recognizes the given value.