doc: contract, clarifications (#3061)

- reword the first-page explanation of chaperone contracts;
  try to give a positive description by talking about wrappers first
  (rather than starting with what chaperones maybe don't do)

- name the recognizer functions for chaperone & impersonator contracts
  (on the first page)

- clarify that `contract-projection` and `contract-val-first-projection`
  are bad --- that there's a preferred alternative

- describe the outputs of `contract-projection` and
  `contract-val-first-projection`; their docs were identical before, but
  now re-use prose from sec 8.7 (Building New Contract Combinators)
This commit is contained in:
Ben Greenman 2020-03-01 08:49:36 -05:00 committed by GitHub
parent 24cdc58951
commit a57f96ea9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -91,26 +91,27 @@ Contracts in Racket are subdivided into three different categories:
in this library can be used directly as predicates, but ordinary in this library can be used directly as predicates, but ordinary
Racket values that double as flat contracts (e.g., numbers or symbols) Racket values that double as flat contracts (e.g., numbers or symbols)
cannot. cannot.
The function @racket[flat-contract?] recognizes a flat contract.} The function @racket[flat-contract?] recognizes a flat contract.}
@item{@deftech{Chaperone @tech{contracts}} are not always immediately @item{@deftech{Chaperone @tech{contracts}} may wrap a value in such
checkable, but are guaranteed to not change any properties a way that it signals contract violations later, as the value
of any values that they check. That is, they may wrap is used, but are guaranteed to not otherwise change behavior.
a value in such a way that it signals contract violations For example, a function contract wraps a function value and
later, as the value is used (e.g., a function contract later checks inputs and outputs; any properties that the
checks the inputs and outputs to the function only when function value had before being wrapped by the contract are
the function is called and returned), but any properties preserved by the contract wrapper.
that the value had before being wrapped by the contract
are preserved by the contract wrapper.
All @tech{flat contracts} may be used where @tech{chaperone contracts} are expected All @tech{flat contracts} may be used where @tech{chaperone contracts} are expected
(but not vice-versa).} (but not vice-versa). The function @racket[chaperone-contract?]
@item{@deftech{Impersonator @tech{contracts}} do not provide any recognizes a chaperone contract.}
guarantees about values they check. Impersonator contracts @item{@deftech{Impersonator @tech{contracts}} may wrap values and do
not provide any guarantees. Impersonator contracts
may hide properties of values, or even make them completely may hide properties of values, or even make them completely
opaque (e.g, @racket[new-∀/c]). opaque (e.g, @racket[new-∀/c]).
All @tech{contracts} may be used where impersonator contracts are expected.}] All @tech{contracts} may be used where impersonator contracts are expected.
The function @racket[impersonator-contract?] recognizes an
impersonator contract.}]
For more about this hierarchy, see the section ``@secref["chaperones"]'' For more about this hierarchy, see the section ``@secref["chaperones"]''
as well as a research paper @cite{Strickland12} on chaperones, impersonators, as well as a research paper @cite{Strickland12} on chaperones, impersonators,
@ -3417,13 +3418,20 @@ Produces the name used to describe the contract in error messages.
@defproc[(contract-projection [c contract?]) (-> blame? (-> any/c any/c))]{ @defproc[(contract-projection [c contract?]) (-> blame? (-> any/c any/c))]{
Produces the projection defining a contract's behavior. See also Produces a projection defining a contract's behavior.
@racket[contract-late-neg-projection]. This projection is a curried function of two arguments: the first application
accepts a blame object, and the second accepts a value to protect with the
contract.
If possible, use @racket[contract-late-neg-projection] instead.
} }
@defproc[(contract-val-first-projection [c contract?]) (-> blame? (-> any/c (-> any/c any/c)))]{ @defproc[(contract-val-first-projection [c contract?]) (-> blame? (-> any/c (-> any/c any/c)))]{
Produces the projection defining a contract's behavior. Produces a projection defining a contract's behavior.
See also @racket[contract-late-neg-projection]. This projection is similar to the result of @racket[contract-late-neg-projection]
except with an extra layer of currying.
If possible, use @racket[contract-late-neg-projection] instead.
} }
@defproc[(make-none/c [sexp-name any/c]) contract?]{ @defproc[(make-none/c [sexp-name any/c]) contract?]{