186 lines
No EOL
214 KiB
HTML
186 lines
No EOL
214 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>7.3 Contracts on Functions in General</title><link rel="stylesheet" type="text/css" href="../scribble.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 Guide</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="intro.html" class="tocviewlink" data-pltdoc="x">Welcome to Racket</a></td></tr><tr><td align="right">2 </td><td><a href="to-scheme.html" class="tocviewlink" data-pltdoc="x">Racket Essentials</a></td></tr><tr><td align="right">3 </td><td><a href="datatypes.html" class="tocviewlink" data-pltdoc="x">Built-<wbr></wbr>In Datatypes</a></td></tr><tr><td align="right">4 </td><td><a href="scheme-forms.html" class="tocviewlink" data-pltdoc="x">Expressions and Definitions</a></td></tr><tr><td align="right">5 </td><td><a href="define-struct.html" class="tocviewlink" data-pltdoc="x">Programmer-<wbr></wbr>Defined Datatypes</a></td></tr><tr><td align="right">6 </td><td><a href="modules.html" class="tocviewlink" data-pltdoc="x">Modules</a></td></tr><tr><td align="right">7 </td><td><a href="contracts.html" class="tocviewselflink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">8 </td><td><a href="i_o.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">9 </td><td><a href="regexp.html" class="tocviewlink" data-pltdoc="x">Regular Expressions</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Exceptions and Control</a></td></tr><tr><td align="right">11 </td><td><a href="for.html" class="tocviewlink" data-pltdoc="x">Iterations and Comprehensions</a></td></tr><tr><td align="right">12 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">13 </td><td><a href="classes.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">14 </td><td><a href="units.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">15 </td><td><a href="reflection.html" class="tocviewlink" data-pltdoc="x">Reflection and Dynamic Evaluation</a></td></tr><tr><td align="right">16 </td><td><a href="macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">17 </td><td><a href="languages.html" class="tocviewlink" data-pltdoc="x">Creating Languages</a></td></tr><tr><td align="right">18 </td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Synchronization</a></td></tr><tr><td align="right">19 </td><td><a href="performance.html" class="tocviewlink" data-pltdoc="x">Performance</a></td></tr><tr><td align="right">20 </td><td><a href="parallelism.html" class="tocviewlink" data-pltdoc="x">Parallelism</a></td></tr><tr><td align="right">21 </td><td><a href="running.html" class="tocviewlink" data-pltdoc="x">Running and Creating Executables</a></td></tr><tr><td align="right">22 </td><td><a href="More_Libraries.html" class="tocviewlink" data-pltdoc="x">More Libraries</a></td></tr><tr><td align="right">23 </td><td><a href="dialects.html" class="tocviewlink" data-pltdoc="x">Dialects of Racket and Scheme</a></td></tr><tr><td align="right">24 </td><td><a href="other-editors.html" class="tocviewlink" data-pltdoc="x">Command-<wbr></wbr>Line Tools and Your Editor of Choice</a></td></tr><tr><td align="right"></td><td><a href="doc-bibliography.html" class="tocviewlink" data-pltdoc="x">Bibliography</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_1");">▼</a></td><td>7 </td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr></table><div class="tocviewsublist" style="display: block;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">7.1 </td><td><a href="contract-boundaries.html" class="tocviewlink" data-pltdoc="x">Contracts and Boundaries</a></td></tr><tr><td align="right">7.2 </td><td><a href="contract-func.html" class="tocviewlink" data-pltdoc="x">Simple Contracts on Functions</a></td></tr><tr><td align="right">7.3 </td><td><a href="contracts-general-functions.html" class="tocviewselflink" data-pltdoc="x">Contracts on Functions in General</a></td></tr><tr><td align="right">7.4 </td><td><a href="contracts-first.html" class="tocviewlink" data-pltdoc="x">Contracts:<span class="mywbr"> </span> A Thorough Example</a></td></tr><tr><td align="right">7.5 </td><td><a href="contracts-struct.html" class="tocviewlink" data-pltdoc="x">Contracts on Structures</a></td></tr><tr><td align="right">7.6 </td><td><a href="contracts-exists.html" class="tocviewlink" data-pltdoc="x">Abstract Contracts using <span class="RktPn">#:<span class="mywbr"> </span>exists</span> and <span class="RktPn">#:<span class="mywbr"> </span>∃</span></a></td></tr><tr><td align="right">7.7 </td><td><a href="contracts-examples.html" class="tocviewlink" data-pltdoc="x">Additional Examples</a></td></tr><tr><td align="right">7.8 </td><td><a href="Building_New_Contracts.html" class="tocviewlink" data-pltdoc="x">Building New Contracts</a></td></tr><tr><td align="right">7.9 </td><td><a href="contracts-gotchas.html" class="tocviewlink" data-pltdoc="x">Gotchas</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_2");">►</a></td><td>7.3 </td><td><a href="contracts-general-functions.html" class="tocviewselflink" data-pltdoc="x">Contracts on Functions in General</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_2"><table cellspacing="0" cellpadding="0"><tr><td align="right">7.3.1 </td><td><a href="contracts-general-functions.html#%28part._contracts-optional%29" class="tocviewlink" data-pltdoc="x">Optional Arguments</a></td></tr><tr><td align="right">7.3.2 </td><td><a href="contracts-general-functions.html#%28part._contracts-rest-args%29" class="tocviewlink" data-pltdoc="x">Rest Arguments</a></td></tr><tr><td align="right">7.3.3 </td><td><a href="contracts-general-functions.html#%28part._contracts-keywords%29" class="tocviewlink" data-pltdoc="x">Keyword Arguments</a></td></tr><tr><td align="right">7.3.4 </td><td><a href="contracts-general-functions.html#%28part._contracts-optional-keywords%29" class="tocviewlink" data-pltdoc="x">Optional Keyword Arguments</a></td></tr><tr><td align="right">7.3.5 </td><td><a href="contracts-general-functions.html#%28part._contracts-case-lambda%29" class="tocviewlink" data-pltdoc="x">Contracts for <span class="RktSym"><span class="RktStxLink">case-<wbr></wbr>lambda</span></span></a></td></tr><tr><td align="right">7.3.6 </td><td><a href="contracts-general-functions.html#%28part._contracts-arrow-d%29" class="tocviewlink" data-pltdoc="x">Argument and Result Dependencies</a></td></tr><tr><td align="right">7.3.7 </td><td><a href="contracts-general-functions.html#%28part._contracts-arrow-d-eval-order%29" class="tocviewlink" data-pltdoc="x">Checking State Changes</a></td></tr><tr><td align="right">7.3.8 </td><td><a href="contracts-general-functions.html#%28part._contracts-multiple%29" class="tocviewlink" data-pltdoc="x">Multiple Result Values</a></td></tr><tr><td align="right">7.3.9 </td><td><a href="contracts-general-functions.html#%28part._contracts-no-domain%29" class="tocviewlink" data-pltdoc="x">Fixed but Statically Unknown Arities</a></td></tr></table></div></div></div><div class="tocsub"><div class="tocsubtitle">On this page:</div><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">7.3.1<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-optional%29" class="tocsubseclink" data-pltdoc="x">Optional Arguments</a></td></tr><tr><td><span class="tocsublinknumber">7.3.2<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-rest-args%29" class="tocsubseclink" data-pltdoc="x">Rest Arguments</a></td></tr><tr><td><span class="tocsublinknumber">7.3.3<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-keywords%29" class="tocsubseclink" data-pltdoc="x">Keyword Arguments</a></td></tr><tr><td><span class="tocsublinknumber">7.3.4<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-optional-keywords%29" class="tocsubseclink" data-pltdoc="x">Optional Keyword Arguments</a></td></tr><tr><td><span class="tocsublinknumber">7.3.5<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-case-lambda%29" class="tocsubseclink" data-pltdoc="x">Contracts for <span class="RktSym"><span class="RktStxLink">case-<wbr></wbr>lambda</span></span></a></td></tr><tr><td><span class="tocsublinknumber">7.3.6<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-arrow-d%29" class="tocsubseclink" data-pltdoc="x">Argument and Result Dependencies</a></td></tr><tr><td><span class="tocsublinknumber">7.3.7<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-arrow-d-eval-order%29" class="tocsubseclink" data-pltdoc="x">Checking State Changes</a></td></tr><tr><td><span class="tocsublinknumber">7.3.8<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-multiple%29" class="tocsubseclink" data-pltdoc="x">Multiple Result Values</a></td></tr><tr><td><span class="tocsublinknumber">7.3.9<tt> </tt></span><a href="contracts-general-functions.html#%28part._contracts-no-domain%29" class="tocsubseclink" data-pltdoc="x">Fixed but Statically Unknown Arities</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="navsettop"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "8.6", "../");"/></form> <a href="https://docs.racket-lang.org/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="contract-func.html" title="backward to "7.2 Simple Contracts on Functions"" data-pltdoc="x">← prev</a> <a href="contracts.html" title="up to "7 Contracts"" data-pltdoc="x">up</a> <a href="contracts-first.html" title="forward to "7.4 Contracts: A Thorough Example"" data-pltdoc="x">next →</a></span> </div><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-general-functions"">7.3<tt> </tt><a name="(part._contracts-general-functions)"></a>Contracts on Functions in General</h4><p>The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span> contract constructor works for functions that take a
|
|
fixed number of arguments and where the result contract is independent
|
|
of the input arguments. To support other kinds of functions, Racket
|
|
supplies additional contract constructors, notably <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span> and
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span>.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-optional"">7.3.1<tt> </tt><a name="(part._contracts-optional)"></a>Optional Arguments</h5><p>Take a look at this excerpt from a string-processing module:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><a href="Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace"> </span><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">pad the given str left and right with</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the (optional) char so that it is centered</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">string-pad-center</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._natural-number%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">natural-number/c</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string-pad-center</span><span class="hspace"> </span><span class="RktSym">str</span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">pad</span><span class="hspace"> </span><span class="RktVal">#\space</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">field-width</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._min%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">min</a></span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">str</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">rmargin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._ceiling%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">ceiling</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252F%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._-%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktSym">field-width</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">lmargin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._floor%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">floor</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252F%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._-%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktSym">field-width</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-append%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._build-string%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">build-string</a></span><span class="hspace"> </span><span class="RktSym">lmargin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">pad</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">str</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._build-string%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">build-string</a></span><span class="hspace"> </span><span class="RktSym">rmargin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">pad</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>The module exports <span class="RktSym">string-pad-center</span>, a function
|
|
that creates a string of a given <span class="RktSym">width</span> with the
|
|
given string in the center. The default fill character is
|
|
<span class="RktVal">#\space</span>; if the client module wishes to use a
|
|
different character, it may call <span class="RktSym">string-pad-center</span>
|
|
with a third argument, a <span class="RktSym">char</span>, overwriting the
|
|
default.</p><p>The function definition uses optional arguments, which is
|
|
appropriate for this kind of functionality. The interesting
|
|
point here is the formulation of the contract for the
|
|
<span class="RktSym">string-pad-center</span>.</p><p>The contract combinator <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span>, demands several groups of contracts:</p><ul><li><p>The first one is a parenthesized group of contracts for all required
|
|
arguments. In this example, we see two: <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span> and
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._natural-number%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">natural-number/c</a></span>. </p></li><li><p>The second one is a parenthesized group of contracts for all optional
|
|
arguments: <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span>. </p></li><li><p>The last one is a single contract: the result of the function.</p></li></ul><p>Note that if a default value does not satisfy a contract, you won’t get a
|
|
contract error for this interface. If you can’t trust yourself to get
|
|
the initial value right, you need to communicate the initial value
|
|
across a boundary.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-rest-args"">7.3.2<tt> </tt><a name="(part._contracts-rest-args)"></a>Rest Arguments</h5><p>The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._max%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">max</a></span> operator consumes at least one real number, but it
|
|
accepts any number of additional arguments. You can write other such
|
|
functions using a <a href="lambda.html#%28tech._rest._argument%29" class="techoutside" data-pltdoc="x"><span class="techinside">rest argument</span></a>, such as in <span class="RktSym">max-abs</span>:</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>See <a href="lambda.html#%28part._rest-args%29" data-pltdoc="x">Declaring a Rest Argument</a> for an introduction to rest
|
|
arguments.</p></blockquote></blockquote></blockquote><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">max-abs</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym">rst</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._foldr%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">m</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._max%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">max</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._abs%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">abs</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">m</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._abs%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">abs</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Describing this function through a contract requires a further
|
|
extension of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span>: a <span class="RktPn">#:rest</span> keyword specifies a
|
|
contract on a list of arguments after the required and optional
|
|
arguments:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">max-abs</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._real%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">real?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">#:rest</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._real%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">real?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._real%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">real?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>As always for <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span>, the contracts for the required arguments
|
|
are enclosed in the first pair of parentheses, which in this case is a
|
|
single real number. The empty pair of parenthesis indicates that there
|
|
are no optional arguments (not counting the rest arguments). The
|
|
contract for the rest argument follows <span class="RktPn">#:rest</span>; since all
|
|
additional arguments must be real numbers, the list of rest arguments
|
|
must satisfy the contract <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="stt"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._real%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">real?</a></span><span class="RktPn">)</span>.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-keywords"">7.3.3<tt> </tt><a name="(part._contracts-keywords)"></a>Keyword Arguments</h5><p>It turns out that the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span> contract constructor also contains
|
|
support for keyword arguments. For example, consider this function,
|
|
which creates a simple GUI and asks the user a yes-or-no question:</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>See <a href="lambda.html#%28part._lambda-keywords%29" data-pltdoc="x">Declaring Keyword Arguments</a> for an introduction to
|
|
keyword arguments.</p></blockquote></blockquote></blockquote><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><a href="Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace"> </span><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket/gui</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ask-yes-or-no-question</span><span class="hspace"> </span><span class="RktSym">question</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:default</span><span class="hspace"> </span><span class="RktSym">answer</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:title</span><span class="hspace"> </span><span class="RktSym">title</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:width</span><span class="hspace"> </span><span class="RktSym">w</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:height</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">d</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=dialog_.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">dialog%</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">label</span><span class="hspace"> </span><span class="RktSym">title</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">height</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">msg</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=message_.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">message%</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">label</span><span class="hspace"> </span><span class="RktSym">question</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktSym">d</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">yes</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">answer</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">d</span><span class="hspace"> </span><span class="RktSym">show</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">no</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">answer</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">d</span><span class="hspace"> </span><span class="RktSym">show</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">yes-b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=button_.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">button%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">label</span><span class="hspace"> </span><span class="RktVal">"Yes"</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktSym">d</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">callback</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">yes</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">style</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._if%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktSym">answer</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">border</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">no-b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=button_.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">button%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">label</span><span class="hspace"> </span><span class="RktVal">"No"</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktSym">d</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">callback</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">no</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">style</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._if%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktSym">answer</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">border</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">d</span><span class="hspace"> </span><span class="RktSym">show</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">answer</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">ask-yes-or-no-question</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:default</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=booleans.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._boolean%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">boolean?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:title</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:width</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._exact-integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">exact-integer?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:height</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._exact-integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">exact-integer?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=booleans.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._boolean%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">boolean?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>If you really want to ask a yes-or-no question
|
|
via a GUI, you should use <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=Windowing_Functions.html%23%2528def._%2528%2528lib._mred%252Fmain..rkt%2529._message-box%252Fcustom%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">message-box/custom</a></span>. For that
|
|
matter, it’s usually better to provide buttons with more specific
|
|
answers than “yes” and “no.”</p></blockquote></blockquote></blockquote><p>The contract for <span class="RktSym">ask-yes-or-no-question</span> uses <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span>, and
|
|
in the same way that <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span> (or <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span>-based
|
|
functions) allows a keyword to precede a functions formal argument,
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span> allows a keyword to precede a function contract’s argument
|
|
contract. In this case,
|
|
the contract says that <span class="RktSym">ask-yes-or-no-question</span> must receive four keyword
|
|
arguments, one for each of the keywords
|
|
<span class="RktPn">#:default</span>,
|
|
<span class="RktPn">#:title</span>,
|
|
<span class="RktPn">#:width</span>, and
|
|
<span class="RktPn">#:height</span>.
|
|
As in a function definition, the order of the keywords in <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span>
|
|
relative to each other does not matter for clients of the function;
|
|
only the relative order of argument contracts without keywords
|
|
matters.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-optional-keywords"">7.3.4<tt> </tt><a name="(part._contracts-optional-keywords)"></a>Optional Keyword Arguments</h5><p>Of course, many of the parameters in
|
|
<span class="RktSym">ask-yes-or-no-question</span> (from the previous question)
|
|
have reasonable defaults and should be made optional:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ask-yes-or-no-question</span><span class="hspace"> </span><span class="RktSym">question</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:default</span><span class="hspace"> </span><span class="RktSym">answer</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:title</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktVal">"Yes or No?"</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:width</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">w</span><span class="hspace"> </span><span class="RktVal">400</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:height</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktVal">200</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._......%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote><p>To specify this function’s contract, we need to use
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span> again. It supports keywords just as you might
|
|
expect in both the optional and mandatory argument
|
|
sections. In this case, we have the mandatory keyword
|
|
<span class="RktPn">#:default</span> and optional keywords
|
|
<span class="RktPn">#:title</span>,
|
|
<span class="RktPn">#:width</span>, and
|
|
<span class="RktPn">#:height</span>. So, we write the contract like this:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">ask-yes-or-no-question</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:default</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=booleans.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._boolean%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">boolean?</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">#:title</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:width</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._exact-integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">exact-integer?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:height</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._exact-integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">exact-integer?</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=booleans.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._boolean%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">boolean?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>That is, we put the mandatory keywords in the first section, and we
|
|
put the optional ones in the second section.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-case-lambda"">7.3.5<tt> </tt><a name="(part._contracts-case-lambda)"></a>Contracts for <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._case-lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-lambda</a></span></h5><p>A function defined with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._case-lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-lambda</a></span> might impose different
|
|
constraints on its arguments depending on how many are provided. For
|
|
example, a <span class="RktSym">report-cost</span> function might convert either a pair
|
|
of numbers or a string into a new string:</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>See <a href="lambda.html#%28part._case-lambda%29" data-pltdoc="x">Arity-Sensitive Functions: <span class="RktSym"><span class="RktStxLink">case-lambda</span></span></a> for an introduction to
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._case-lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-lambda</a></span>.</p></blockquote></blockquote></blockquote><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">report-cost</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._case-lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-lambda</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">lo</span><span class="hspace"> </span><span class="RktSym">hi</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._format%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"between $~a and $~a"</span><span class="hspace"> </span><span class="RktSym">lo</span><span class="hspace"> </span><span class="RktSym">hi</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">desc</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._format%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a of dollars"</span><span class="hspace"> </span><span class="RktSym">desc</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">report-cost</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">8</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"between $5 and $8"</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">report-cost</span><span class="hspace"> </span><span class="RktVal">"millions"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"millions of dollars"</span></p></td></tr></table></td></tr></table></blockquote><p><div class="SIntrapara">The contract for such a function is formed with the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._case-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-></a></span>
|
|
combinator, which combines as many functional contracts as needed:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">report-cost</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._case-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">case-></a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">integer?</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._integer%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">integer?</a></span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As you can see, the contract for <span class="RktSym">report-cost</span> combines two
|
|
function contracts, which is just as many clauses as the explanation
|
|
of its functionality required.</div></p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-arrow-d"">7.3.6<tt> </tt><a name="(part._contracts-arrow-d)"></a>Argument and Result Dependencies</h5><p>The following is an excerpt from an imaginary numerics module:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">real-sqrt</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">argument</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._%7E3e%7E3d%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">>=/c</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">result</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">argument</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._%7E3c%7E3d%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><=/c</a></span><span class="hspace"> </span><span class="RktSym">argument</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p><div class="SIntrapara"><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>The word “indy” is meant to suggest that blame may be
|
|
assigned to the contract itself, because the contract must be considered an
|
|
independent component. The name was chosen in
|
|
response to two existing labels—<wbr></wbr>“lax” and “picky”—<wbr></wbr>for different
|
|
semantics of function contracts in the research literature.</p></blockquote></blockquote></blockquote></div><div class="SIntrapara">The contract for the exported function <span class="RktSym">real-sqrt</span> uses the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span> rather than <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span> function contract. The “i”
|
|
stands for an <span style="font-style: italic">indy dependent</span> contract, meaning the contract for the
|
|
function range depends on the value of the argument. The appearance
|
|
of <span class="RktSym">argument</span> in the line for <span class="RktSym">result</span>’s contract means
|
|
that the result depends on the argument. In this
|
|
particular case, the argument of <span class="RktSym">real-sqrt</span> is greater or
|
|
equal to 1, so a very basic correctness check is that the result is
|
|
smaller than the argument.</div></p><p>In general, a dependent function contract looks just like
|
|
the more general <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span> contract, but with names added
|
|
that can be used elsewhere in the contract.</p><p>Going back to the bank-account example, suppose that we generalize the
|
|
module to support multiple accounts and that we also include a
|
|
withdrawal operation. The improved bank-account module includes an
|
|
<span class="RktSym">account</span> structure type and the following functions:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">withdraw</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">deposit</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Besides requiring that a client provide a valid amount for a
|
|
withdrawal, however, the amount should be less than or equal to the specified
|
|
account’s balance, and the resulting account will have less money than
|
|
it started with. Similarly, the module might promise that a deposit
|
|
produces an account with money added to the account. The following
|
|
implementation enforces those constraints and guarantees through
|
|
contracts:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><a href="Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace"> </span><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 1: the contract definitions</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define-struct.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._struct%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">struct</a></span><span class="hspace"> </span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._natural-number%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">natural-number/c</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 2: the exports</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">create</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">withdraw</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._%7E3c%7E3d%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><=/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">result</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktSym">account?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">res</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3e%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">res</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._-%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">deposit</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">result</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktSym">account?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">res</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3e%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">res</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 3: the function definitions</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">account-balance</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">withdraw</span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._-%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account-balance</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">deposit</span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account-balance</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>The contracts in section 2 provide typical type-like guarantees for
|
|
<span class="RktSym">create</span> and <span class="RktSym">balance</span>. For <span class="RktSym">withdraw</span> and
|
|
<span class="RktSym">deposit</span>, however, the contracts check and guarantee the more
|
|
complicated constraints on <span class="RktSym">balance</span> and <span class="RktSym">deposit</span>. The
|
|
contract on the second argument to <span class="RktSym">withdraw</span> uses
|
|
<span class="RktPn">(</span><span class="RktSym">balance</span><span class="stt"> </span><span class="RktSym">acc</span><span class="RktPn">)</span> to check whether the supplied withdrawal amount
|
|
is small enough, where <span class="RktSym">acc</span> is the name given within
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span> to the function’s first argument. The contract on the
|
|
result of <span class="RktSym">withdraw</span> uses both <span class="RktSym">acc</span> and <span class="RktSym">amt</span> to
|
|
guarantee that no more than that requested amount was withdrawn. The
|
|
contract on <span class="RktSym">deposit</span> similarly uses <span class="RktSym">acc</span> and
|
|
<span class="RktSym">amount</span> in the result contract to guarantee that at least as
|
|
much money as provided was deposited into the account.</p><p>As written above, when a contract check fails, the error message is
|
|
not great. The following revision uses <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._flat-named-contract%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">flat-named-contract</a></span>
|
|
within a helper function <span class="RktSym">mk-account-contract</span> to provide
|
|
better error messages.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><a href="Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace"> </span><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 1: the contract definitions</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define-struct.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._struct%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">struct</a></span><span class="hspace"> </span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._natural-number%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">natural-number/c</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">msg></span><span class="hspace"> </span><span class="RktVal">"account a with balance larger than ~a expected"</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">msg<</span><span class="hspace"> </span><span class="RktVal">"account a with balance less than ~a expected"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-account-contract</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym">op</span><span class="hspace"> </span><span class="RktSym">msg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">balance0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ctr</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._and%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">op</span><span class="hspace"> </span><span class="RktSym">balance0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._flat-named-contract%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">flat-named-contract</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._format%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktSym">msg</span><span class="hspace"> </span><span class="RktSym">balance0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ctr</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 2: the exports</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">create</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account?</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">withdraw</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._%7E3c%7E3d%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><=/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">result</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-account-contract</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3e%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktSym">msg></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">deposit</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">account?</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym">amount/c</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">result</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-account-contract</span><span class="hspace"> </span><span class="RktSym">acc</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3c%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktSym">msg<</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">section 3: the function definitions</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">balance</span><span class="hspace"> </span><span class="RktSym">account-balance</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">withdraw</span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._-%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account-balance</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">deposit</span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">account-balance</span><span class="hspace"> </span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-arrow-d-eval-order"">7.3.7<tt> </tt><a name="(part._contracts-arrow-d-eval-order)"></a>Checking State Changes</h5><p><div class="SIntrapara">The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span> contract combinator can also ensure that a
|
|
function only modifies state according to certain
|
|
constraints. For example, consider this contract
|
|
(it is a slightly simplified version from the function
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=framework&rel=Preferences.html%23%2528def._%2528%2528lib._framework%252Fmain..rkt%2529._preferences%7E3aadd-panel%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">preferences:add-panel</a></span> in the framework):
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528def._%2528%2528lib._racket%252Fclass..rkt%2529._is-a%7E3f%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?/c</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=area-container-window___.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">area-container-window<%></a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529.__%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">parent</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">old-children</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktSym">get-children</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">child</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fmap..rkt%2529._andmap%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">andmap</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Equality.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eq%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eq?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._append%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">append</a></span><span class="hspace"> </span><span class="RktSym">old-children</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">child</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">parent</span><span class="hspace"> </span><span class="RktSym">get-children</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It says that the function accepts a single argument, named
|
|
<span class="RktSym">parent</span>, and that <span class="RktSym">parent</span> must be
|
|
an object matching the interface <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=area-container-window___.html&version=8.6" class="RktValLink Sq" data-pltdoc="x">area-container-window<%></a></span>.</div></p><p>The range contract ensures that the function only modifies
|
|
the children of <span class="RktSym">parent</span> by adding a new child to the
|
|
front of the list. It accomplishes this by using the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529.__%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">_</a></span> instead of a normal identifier, which tells the
|
|
contract library that the range contract does not depend on
|
|
the values of any of the results, and thus the contract
|
|
library evaluates the expression following the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529.__%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">_</a></span>
|
|
when the function is called, instead of when it
|
|
returns. Therefore the call to the <span class="RktSym">get-children</span> method
|
|
happens before the function under the contract is called.
|
|
When the function under contract returns, its result is
|
|
passed in as <span class="RktSym">child</span>, and the contract ensures that
|
|
the children after the function return are the same as the
|
|
children before the function called, but with one more
|
|
child, at the front of the list.</p><p><div class="SIntrapara">To see the difference in a toy example that focuses
|
|
on this point, consider this program
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><a href="Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace"> </span><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">f</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529.__%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">ctc</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._any%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">any/c</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">get-x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=symbols.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._symbol%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">symbol?</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you were to require this module, call <span class="RktSym">f</span>, then
|
|
the result of <span class="RktSym">get-x</span> would be <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">f</span><span class="stt"> </span><span class="RktVal">ctc</span><span class="RktVal">)</span>. In
|
|
contrast, if the contract for <span class="RktSym">f</span> were
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">res</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">ctc</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._any%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">any/c</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">(only changing the underscore to <span class="RktSym">res</span>), then
|
|
the result of <span class="RktSym">get-x</span> would be <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">ctc</span><span class="stt"> </span><span class="RktVal">f</span><span class="RktVal">)</span>.</div></p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-multiple"">7.3.8<tt> </tt><a name="(part._contracts-multiple)"></a>Multiple Result Values</h5><p><div class="SIntrapara">The function <span class="RktSym">split</span> consumes a list of <span class="RktSym">char</span>s
|
|
and delivers the string that occurs before the first occurrence of
|
|
<span class="RktVal">#\newline</span> (if any) and the rest of the list:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._cond%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._null%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">null?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list-%7E3estring%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list->string</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._reverse%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">reverse</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3d%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char=?</a></span><span class="hspace"> </span><span class="RktVal">#\newline</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._car%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">car</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list-%7E3estring%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list->string</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._reverse%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">reverse</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cdr%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cdr</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._else%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cdr%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cdr</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._car%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">car</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It is a typical multiple-value function, returning two values by
|
|
traversing a single list.</div></p><p><div class="SIntrapara">The contract for such a function can use the ordinary
|
|
function arrow <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span>, since <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span>
|
|
treats <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span> specially when it appears as the
|
|
last result:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The contract for such a function can also be written
|
|
using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As before, the contract for the argument with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span> is wrapped in an
|
|
extra pair of parentheses (and must always be wrapped like
|
|
that) and the empty pair of parentheses indicates that
|
|
there are no optional arguments. The contracts for the
|
|
results are inside <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span>: a string and a list of
|
|
characters.</div></p><p><div class="SIntrapara">Now, suppose that we also want to ensure that the first result of
|
|
<span class="RktSym">split</span> is a prefix of the given word in list format. In that
|
|
case, we need to use the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span> contract combinator:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">substring-of?</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._flat-named-contract%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">flat-named-contract</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._format%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"substring of ~s"</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">s2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._and%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3c%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Equality.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._equal%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._substring%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">substring</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">fl</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fl</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">substring-of?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=strings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list-%7E3estring%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list->string</a></span><span class="hspace"> </span><span class="RktSym">fl</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span>, the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span> combinator uses a function over the
|
|
argument to create the range contracts. Yes, it doesn’t just return one
|
|
contract but as many as the function produces values: one contract per
|
|
value. In this case, the second contract is the same as before, ensuring
|
|
that the second result is a list of <span class="RktSym">char</span>s. In contrast, the
|
|
first contract strengthens the old one so that the result is a prefix of
|
|
the given word.</div></p><p><div class="SIntrapara">This contract is expensive to check, of course. Here is a
|
|
cheaper, though less stringent, version:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">split</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">fl</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fl</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._string-len%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">string-len/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">length</a></span><span class="hspace"> </span><span class="RktSym">fl</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=characters.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._char%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">char?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Why did we add <span class="RktVal">1</span> to the length of <span class="RktSym">fl</span>?</div></p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""contracts-no-domain"">7.3.9<tt> </tt><a name="(part._contracts-no-domain)"></a>Fixed but Statically Unknown Arities</h5><p>Imagine yourself writing a contract for a function that accepts some other
|
|
function and a list of numbers that eventually applies the former to the
|
|
latter. Unless the arity of the given function matches the length of the
|
|
given list, your procedure is in trouble.</p><p><div class="SIntrapara">Consider this <span class="RktSym">n-step</span> function:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">(number ... -> (union #f number?)) (listof number) -> void</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">n-step</span><span class="hspace"> </span><span class="RktSym">proc</span><span class="hspace"> </span><span class="RktSym">inits</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">inc</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=procedures.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._apply%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">apply</a></span><span class="hspace"> </span><span class="RktSym">proc</span><span class="hspace"> </span><span class="RktSym">inits</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=when_unless.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._when%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">when</a></span><span class="hspace"> </span><span class="RktSym">inc</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">n-step</span><span class="hspace"> </span><span class="RktSym">proc</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fmap..rkt%2529._map%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">inc</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">inits</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>The argument of <span class="RktSym">n-step</span> is <span class="RktSym">proc</span>, a function
|
|
<span class="RktSym">proc</span> whose results are either numbers or false, and a list. It
|
|
then applies <span class="RktSym">proc</span> to the list <span class="RktSym">inits</span>. As long as
|
|
<span class="RktSym">proc</span> returns a number, <span class="RktSym">n-step</span> treats that number
|
|
as an increment for each of the numbers in <span class="RktSym">inits</span> and
|
|
recurs. When <span class="RktSym">proc</span> returns <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=booleans.html%23%2528def._%2528%2528lib._racket%252Fbool..rkt%2529._false%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">false</a></span>, the loop stops.</p><p><div class="SIntrapara">Here are two uses:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">nat -> nat</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._printf%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">printf</a></span><span class="hspace"> </span><span class="RktVal">"~s\n"</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._if%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">n-step</span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">nat nat -> nat</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">g</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">z</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._printf%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">printf</a></span><span class="hspace"> </span><span class="RktVal">"~s\n"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._if%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%7E3d%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktSym">z</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">n-step</span><span class="hspace"> </span><span class="RktSym">g</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">A contract for <span class="RktSym">n-step</span> must specify two aspects of
|
|
<span class="RktSym">proc</span>’s behavior: its arity must include the number of elements
|
|
in <span class="RktSym">inits</span>, and it must return either a number or
|
|
<span class="RktVal">#f</span>. The latter is easy, the former is difficult. At first
|
|
glance, this appears to suggest a contract that assigns a
|
|
<span style="font-style: italic">variable-arity</span> to <span class="RktSym">proc</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3e%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">#:rest</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._any%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">any/c</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._or%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">or/c</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._number%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">number?</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._false%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">false/c</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This contract, however, says that the function must accept <span class="emph">any</span>
|
|
number of arguments, not a <span class="emph">specific</span> but
|
|
<span class="emph">undetermined</span> number. Thus, applying <span class="RktSym">n-step</span> to
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span> breaks the contract
|
|
because the given function accepts only one argument.</div></p><p><div class="SIntrapara">The correct contract uses the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._unconstrained-domain-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">unconstrained-domain-></a></span>
|
|
combinator, which specifies only the range of a function, not its
|
|
domain. It is then possible to combine this contract with an arity test to
|
|
specify the correct contract for <span class="RktSym">n-step</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._contract-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">contract-out</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">n-step</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._-%7E3ei%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>i</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">proc</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inits</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=function-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._unconstrained-domain-%7E3e%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">unconstrained-domain-></a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._or%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">or/c</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._false%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">false/c</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._number%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">number?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._%7Ece%7Ebb%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">λ</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=procedures.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._procedure-arity-includes%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">procedure-arity-includes?</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">f</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._length%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">length</a></span><span class="hspace"> </span><span class="RktSym">inits</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">inits</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._listof%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._number%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">number?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fprivate%252Fmisc..rkt%2529._any%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">any</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "8.6", "../");"/></form> <a href="https://docs.racket-lang.org/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="contract-func.html" title="backward to "7.2 Simple Contracts on Functions"" data-pltdoc="x">← prev</a> <a href="contracts.html" title="up to "7 Contracts"" data-pltdoc="x">up</a> <a href="contracts-first.html" title="forward to "7.4 Contracts: A Thorough Example"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html> |