47 lines
24 KiB
HTML
47 lines
24 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>8 Contracts</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="extras.css" title="default"/><link rel="stylesheet" type="text/css" href="icons.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">►</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">The Racket Reference</a></td></tr></table></div><div class="tocviewsublisttop" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="model.html" class="tocviewlink" data-pltdoc="x">Language Model</a></td></tr><tr><td align="right">2 </td><td><a href="notation.html" class="tocviewlink" data-pltdoc="x">Notation for Documentation</a></td></tr><tr><td align="right">3 </td><td><a href="syntax.html" class="tocviewlink" data-pltdoc="x">Syntactic Forms</a></td></tr><tr><td align="right">4 </td><td><a href="data.html" class="tocviewlink" data-pltdoc="x">Datatypes</a></td></tr><tr><td align="right">5 </td><td><a href="structures.html" class="tocviewlink" data-pltdoc="x">Structures</a></td></tr><tr><td align="right">6 </td><td><a href="mzlib_class.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">7 </td><td><a href="mzlib_unit.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">8 </td><td><a href="contracts.html" class="tocviewselflink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">9 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Control Flow</a></td></tr><tr><td align="right">11 </td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Parallelism</a></td></tr><tr><td align="right">12 </td><td><a href="Macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">13 </td><td><a href="input-and-output.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">14 </td><td><a href="security.html" class="tocviewlink" data-pltdoc="x">Reflection and Security</a></td></tr><tr><td align="right">15 </td><td><a href="os.html" class="tocviewlink" data-pltdoc="x">Operating System</a></td></tr><tr><td align="right">16 </td><td><a href="memory.html" class="tocviewlink" data-pltdoc="x">Memory Management</a></td></tr><tr><td align="right">17 </td><td><a href="unsafe.html" class="tocviewlink" data-pltdoc="x">Unsafe Operations</a></td></tr><tr><t
|
||
|
another. Programmers specify the behavior of a module’s exports via
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29" class="RktStxLink" data-pltdoc="x">provide</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="attaching-contracts-to-values.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._contract-out%29%29" class="RktStxLink" data-pltdoc="x">contract-out</a></span><span class="stt"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span>, and the contract system enforces those
|
||
|
constraints.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="defmodule"><tr><td align="left"><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><a href="contracts.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket/contract</span></a><span class="RktPn">)</span></td><td align="right"><span class="RpackageSpec"><span class="Smaller"> package:</span> <a href="https://pkgs.racket-lang.org/package/base" title="Install this package using `raco pkg install base`"><span class="stt">base</span></a></span></td></tr></table></div><div class="SIntrapara">The bindings documented in this section are provided by the <a href="contracts.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket/contract</span></a> and <a href="index.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket</span></a> libraries, but not <a href="index.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket/base</span></a>.</div></p><p><div class="SIntrapara"><a name="(tech._contract)"></a><span style="font-style: italic">Contracts</span> come in two forms: those constructed by the
|
||
|
various operations listed in this section of the manual, and various
|
||
|
ordinary Racket values that double as contracts, including
|
||
|
</div><div class="SIntrapara"><ul><li><p><a href="symbols.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">symbols</span></a>, <a href="booleans.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">booleans</span></a>, <a href="keywords.html#%28tech._keyword%29" class="techoutside" data-pltdoc="x"><span class="techinside">keywords</span></a>, and
|
||
|
<span class="RktSym"><a href="pairs.html#%28def._%28%28quote._~23~25kernel%29._null%29%29" class="RktValLink" data-pltdoc="x">null</a></span>, which are treated as contracts that recognize
|
||
|
themselves, using <span class="RktSym"><a href="Equality.html#%28def._%28%28quote._~23~25kernel%29._eq~3f%29%29" class="RktValLink" data-pltdoc="x">eq?</a></span>, </p></li><li><p><a href="strings.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">strings</span></a>, <a href="bytestrings.html#%28tech._byte._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">byte strings</span></a>, <a href="characters.html#%28tech._character%29" class="techoutside" data-pltdoc="x"><span class="techinside">characters</span></a>,
|
||
|
<span class="RktVal">+nan.0</span>, and <span class="RktVal">+nan.f</span>, which are treated
|
||
|
as contracts that recognize themselves using <span class="RktSym"><a href="Equality.html#%28def._%28%28quote._~23~25kernel%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span>, </p></li><li><p><a href="numbers.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">numbers</span></a> (except <span class="RktVal">+nan.0</span> and
|
||
|
<span class="RktVal">+nan.f</span>), which are treated as contracts
|
||
|
that recognize themselves using <span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span>,</p></li><li><p><a href="regexp.html#%28tech._regular._expression%29" class="techoutside" data-pltdoc="x"><span class="techinside">regular expressions</span></a>, which are treated as contracts
|
||
|
that recognize <a href="bytestrings.html#%28tech._byte._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">byte strings</span></a> and <a href="strings.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">strings</span></a> that
|
||
|
match the regular expression, and </p></li><li><p>predicates: any procedure of arity 1 is treated as a
|
||
|
predicate. During contract checking, it is applied to the values that
|
||
|
appear and should return <span class="RktVal">#f</span> to indicate that the contract
|
||
|
failed, and anything else to indicate it passed.</p></li></ul></div></p><p><a name="(tech._contract._combinator)"></a><span style="font-style: italic">Contract combinators</span> are functions such as <span class="RktSym"><a href="function-contracts.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._-~3e%29%29" class="RktStxLink" data-pltdoc="x"><span class="nobreak">-></span></a></span> and
|
||
|
<span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._listof%29%29" class="RktValLink" data-pltdoc="x">listof</a></span> that take contracts and produce other contracts.</p><p><div class="SIntrapara">Contracts in Racket are subdivided into three different categories:
|
||
|
</div><div class="SIntrapara"><ul><li><p><a name="(tech._flat._contract)"></a><span style="font-style: italic">Flat <a href="contracts.html#%28tech._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">contracts</span></a></span> can be fully checked immediately for
|
||
|
a given value. These kinds of <a href="contracts.html#%28tech._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">contracts</span></a> are essentially
|
||
|
predicate functions. Using <span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt%29._flat-contract-predicate%29%29" class="RktValLink" data-pltdoc="x">flat-contract-predicate</a></span>,
|
||
|
you can extract the predicate from an arbitrary flat contract; some
|
||
|
flat contracts can be applied like functions, in which case
|
||
|
they accept a single argument and return <span class="RktVal">#t</span> or
|
||
|
<span class="RktVal">#f</span> to indicate if the given value would be accepted
|
||
|
by the contract. All of the flat contracts returned by functions
|
||
|
in this library can be used directly as predicates, but ordinary
|
||
|
Racket values that double as flat contracts (e.g., numbers or symbols)
|
||
|
cannot.</p><p>The function <span class="RktSym"><a href="contract-utilities.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fguts..rkt%29._flat-contract~3f%29%29" class="RktValLink" data-pltdoc="x">flat-contract?</a></span> recognizes a flat contract.</p></li><li><p><a name="(tech._chaperone._contract)"></a><span style="font-style: italic">Chaperone <a href="contracts.html#%28tech._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">contracts</span></a></span> may wrap a value in such
|
||
|
a way that it signals contract violations later, as the value
|
||
|
is used, but are guaranteed to not otherwise change behavior.
|
||
|
For example, a function contract wraps a function value and
|
||
|
later checks inputs and outputs; any properties that the
|
||
|
function value had before being wrapped by the contract are
|
||
|
preserved by the contract wrapper.</p><p>All <a href="contracts.html#%28tech._flat._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">flat contracts</span></a> may be used where <a href="contracts.html#%28tech._chaperone._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">chaperone contracts</span></a> are expected
|
||
|
(but not vice-versa). The function <span class="RktSym"><a href="contract-utilities.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fguts..rkt%29._chaperone-contract~3f%29%29" class="RktValLink" data-pltdoc="x">chaperone-contract?</a></span>
|
||
|
recognizes a chaperone contract.</p></li><li><p><a name="(tech._impersonator._contract)"></a><span style="font-style: italic">Impersonator <a href="contracts.html#%28tech._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">contracts</span></a></span> may wrap values and do
|
||
|
not provide any guarantees. Impersonator contracts
|
||
|
may hide properties of values, or even make them completely
|
||
|
opaque (e.g, <span class="RktSym"><a href="parametric-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fparametric..rkt%29._new-~e2~88~80%2Fc%29%29" class="RktValLink" data-pltdoc="x">new-∀/c</a></span>).</p><p>All <a href="contracts.html#%28tech._contract%29" class="techoutside" data-pltdoc="x"><span class="techinside">contracts</span></a> may be used where impersonator contracts are expected.
|
||
|
The function <span class="RktSym"><a href="contract-utilities.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fguts..rkt%29._impersonator-contract~3f%29%29" class="RktValLink" data-pltdoc="x">impersonator-contract?</a></span> recognizes an
|
||
|
impersonator contract.</p></li></ul></div></p><p>For more about this hierarchy, see the section “<a href="chaperones.html" data-pltdoc="x">Impersonators and Chaperones</a>”
|
||
|
as well as a research paper [<a href="doc-bibliography.html#%28cite._.Strickland12%29" data-pltdoc="x">Strickland12</a>] on chaperones, impersonators,
|
||
|
and how they can be used to implement contracts.</p><p class="SHistory">Changed in version 6.1.1.8 of package <span class="stt">base</span>: Changed <span class="RktVal">+nan.0</span> and <span class="RktVal">+nan.f</span> to
|
||
|
be <span class="RktSym"><a href="Equality.html#%28def._%28%28quote._~23~25kernel%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span>-based contracts.</p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><a href="data-structure-contracts.html" class="toclink" data-pltdoc="x">8.1<span class="hspace"> </span>Data-structure Contracts</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="function-contracts.html" class="toclink" data-pltdoc="x">8.2<span class="hspace"> </span>Function Contracts</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="parametric-contracts.html" class="toclink" data-pltdoc="x">8.3<span class="hspace"> </span>Parametric Contracts</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Lazy_Data-structure_Contracts.html" class="toclink" data-pltdoc="x">8.4<span class="hspace"> </span>Lazy Data-structure Contracts</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Structure_Type_Property_Contracts.html" class="toclink" data-pltdoc="x">8.5<span class="hspace"> </span>Structure Type Property Contracts</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="attaching-contracts-to-values.html" class="toclink" data-pltdoc="x">8.6<span class="hspace"> </span>Attaching Contracts to Values</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="attaching-contracts-to-values.html#%28part._.Nested_.Contract_.Boundaries%29" class="toclink" data-pltdoc="x">8.6.1<span class="hspace"> </span>Nested Contract Boundaries</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="attaching-contracts-to-values.html#%28part._.Low-level_.Contract_.Boundaries%29" class="toclink" data-pltdoc="x">8.6.2<span class="hspace"> </span>Low-level Contract Boundaries</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Building_New_Contract_Combinators.html" class="toclink" data-pltdoc="x">8.7<span class="hspace"> </span>Building New Contract Combinators</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Building_New_Contract_Combinators.html#%28part._.Blame_.Objects%29" class="toclink" data-pltdoc="x">8.7.1<span class="hspace"> </span>Blame Objects</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Building_New_Contract_Combinators.html#%28part._.Contracts_as_structs%29" class="toclink" data-pltdoc="x">8.7.2<span class="hspace"> </span>Contracts as structs</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Building_New_Contract_Combinators.html#%28part._.Obligation_.Information_in_.Check_.Syntax%29" class="toclink" data-pltdoc="x">8.7.3<span class="hspace"> </span>Obligation Information in Check Syntax</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="Building_New_Contract_Combinators.html#%28part._.Utilities_for_.Building_.New_.Combinators%29" class="toclink" data-pltdoc="x">8.7.4<span class="hspace"> </span>Utilities for Building New Combinators</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="contract-utilities.html" class="toclink" data-pltdoc="x">8.8<span class="hspace"> </span>Contract Utilities</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="racket_contract_base.html" class="toclink" data-pltdoc="x">8.9<span class="hspace"> </span><span class="RktModLink"><span class="RktSym">racket/contract/base</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="collapsible.html" class="toclink" data-pltdoc="x">8.10<span class="hspace"> </span>Collapsible Contrac
|