1576 lines
No EOL
1 MiB
1576 lines
No EOL
1 MiB
<!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>III Abstraction</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="shared.css" title="default"/><link rel="stylesheet" type="text/css" href="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="figure.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"/><script type="text/javascript" src="scribble-common.js"></script><script type="text/javascript" src="figure.js"></script><script type="text/javascript" src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="scribble-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">How to Design Programs, Second Edition</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right"></td><td><a href="part_preface.html" class="tocviewlink" data-pltdoc="x">Preface</a></td></tr><tr><td align="right"></td><td><a href="part_prologue.html" class="tocviewlink" data-pltdoc="x">Prologue:<span class="mywbr"> </span> How to Program</a></td></tr><tr><td align="right">I </td><td><a href="part_one.html" class="tocviewlink" data-pltdoc="x">Fixed-<wbr></wbr>Size Data</a></td></tr><tr><td align="right"></td><td><a href="i1-2.html" class="tocviewlink" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a></td></tr><tr><td align="right">II </td><td><a href="part_two.html" class="tocviewlink" data-pltdoc="x">Arbitrarily Large Data</a></td></tr><tr><td align="right"></td><td><a href="i2-3.html" class="tocviewlink" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a></td></tr><tr><td align="right">III </td><td><a href="part_three.html" class="tocviewselflink" data-pltdoc="x">Abstraction</a></td></tr><tr><td align="right"></td><td><a href="i3-4.html" class="tocviewlink" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a></td></tr><tr><td align="right">IV </td><td><a href="part_four.html" class="tocviewlink" data-pltdoc="x">Intertwined Data</a></td></tr><tr><td align="right"></td><td><a href="i4-5.html" class="tocviewlink" data-pltdoc="x">Intermezzo 4: The Nature of Numbers</a></td></tr><tr><td align="right">V </td><td><a href="part_five.html" class="tocviewlink" data-pltdoc="x">Generative Recursion</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html" class="tocviewlink" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a></td></tr><tr><td align="right">VI </td><td><a href="part_six.html" class="tocviewlink" data-pltdoc="x">Accumulators</a></td></tr><tr><td align="right"></td><td><a href="part_epilogue.html" class="tocviewlink" data-pltdoc="x">Epilogue:<span class="mywbr"> </span> Moving On</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>III </td><td><a href="part_three.html" class="tocviewselflink" data-pltdoc="x">Abstraction</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">14 </td><td><a href="part_three.html#%28part._ch~3add-similarities%29" class="tocviewlink" data-pltdoc="x">Similarities Everywhere</a></td></tr><tr><td align="right">15 </td><td><a href="part_three.html#%28part._ch~3aabstract%29" class="tocviewlink" data-pltdoc="x">Designing Abstractions</a></td></tr><tr><td align="right">16 </td><td><a href="part_three.html#%28part._ch~3a3use%29" class="tocviewlink" data-pltdoc="x">Using Abstractions</a></td></tr><tr><td align="right">17 </td><td><a href="part_three.html#%28part._ch~3a3lambda%29" class="tocviewlink" data-pltdoc="x">Nameless Functions</a></td></tr><tr><td align="right">18 </td><td><a href="part_three.html#%28part._ch~3asummary3%29" class="tocviewlink" data-pltdoc="x">Summary</a></td></tr></table></div></div></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="version">8.6.0.2</span></div><div class="navsettop"><span class="navleft"><div class="nosearchform"></div> <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="i2-3.html" title="backward to "Intermezzo 2: Quote, Unquote"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "How to Design Programs, Second Edition"" data-pltdoc="x">up</a> <a href="i3-4.html" title="forward to "Intermezzo 3: Scope and Abstraction"" data-pltdoc="x">next →</a></span> </div><h3>III<tt> </tt><a name="(part._part~3athree)"></a>Abstraction</h3><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._ch~3add-similarities%29" class="toclink" data-pltdoc="x">14<span class="hspace"> </span>Similarities Everywhere</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aprog-similarities%29" class="toclink" data-pltdoc="x">14.1<span class="hspace"> </span>Similarities in Functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3afunc-similarities%29" class="toclink" data-pltdoc="x">14.2<span class="hspace"> </span>Different Similarities</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sim-dd._sec~3add-similarities%29" class="toclink" data-pltdoc="x">14.3<span class="hspace"> </span>Similarities in Data Definitions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3afunctions-as-values%29" class="toclink" data-pltdoc="x">14.4<span class="hspace"> </span>Functions Are Values</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aeval-ho%29" class="toclink" data-pltdoc="x">14.5<span class="hspace"> </span>Computing with Functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._ch~3aabstract%29" class="toclink" data-pltdoc="x">15<span class="hspace"> </span>Designing Abstractions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3adesign-abstract%29" class="toclink" data-pltdoc="x">15.1<span class="hspace"> </span>Abstractions from Examples</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aabs-signatures%29" class="toclink" data-pltdoc="x">15.2<span class="hspace"> </span>Similarities in Signatures</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aspoc%29" class="toclink" data-pltdoc="x">15.3<span class="hspace"> </span>Single Point of Control</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aapriori-abs%29" class="toclink" data-pltdoc="x">15.4<span class="hspace"> </span>Abstractions from Templates</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._ch~3a3use%29" class="toclink" data-pltdoc="x">16<span class="hspace"> </span>Using Abstractions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aisl-abstractions%29" class="toclink" data-pltdoc="x">16.1<span class="hspace"> </span>Existing Abstractions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3alocal-definitions%29" class="toclink" data-pltdoc="x">16.2<span class="hspace"> </span>Local Definitions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3alocal-is-power%29" class="toclink" data-pltdoc="x">16.3<span class="hspace"> </span>Local Definitions Add Expressive Power</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aeval-local%29" class="toclink" data-pltdoc="x">16.4<span class="hspace"> </span>Computing with <span class="RktSym"><span class="RktStxLink">local</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3ausage-examples%29" class="toclink" data-pltdoc="x">16.5<span class="hspace"> </span>Using Abstractions, by Example</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3adesigning-with-abstraction%29" class="toclink" data-pltdoc="x">16.6<span class="hspace"> </span>Designing with Abstractions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aabstraction-exercises%29" class="toclink" data-pltdoc="x">16.7<span class="hspace"> </span>Finger Exercises: Abstraction</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aproj-abstraction%29" class="toclink" data-pltdoc="x">16.8<span class="hspace"> </span>Projects: Abstraction</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._ch~3a3lambda%29" class="toclink" data-pltdoc="x">17<span class="hspace"> </span>Nameless Functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aint-lambda%29" class="toclink" data-pltdoc="x">17.1<span class="hspace"> </span>Functions from <span class="RktSym"><span class="RktStxLink">lambda</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3alambda-technical%29" class="toclink" data-pltdoc="x">17.2<span class="hspace"> </span>Computing with <span class="RktSym"><span class="RktStxLink">lambda</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3alambda%29" class="toclink" data-pltdoc="x">17.3<span class="hspace"> </span>Abstracting with <span class="RktSym"><span class="RktStxLink">lambda</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3aspecification%29" class="toclink" data-pltdoc="x">17.4<span class="hspace"> </span>Specifying with <span class="RktSym"><span class="RktStxLink">lambda</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._sec~3alambda.I.I%29" class="toclink" data-pltdoc="x">17.5<span class="hspace"> </span>Representing with <span class="RktSym"><span class="RktStxLink">lambda</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_three.html#%28part._ch~3asummary3%29" class="toclink" data-pltdoc="x">18<span class="hspace"> </span>Summary</a></p></td></tr></table><p>Many of our data definitions and function definitions look alike. For
|
|
example, the definition for a list of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s differs from that of
|
|
a list of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>s in only two places: the names of the classes of
|
|
data and the words “String” and “Number.” Similarly, a function that
|
|
looks for a specific string in a list of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s is nearly
|
|
indistinguishable from one that looks for a specific number in a list of
|
|
<a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>s.</p><p>Experience shows that these kinds of similarities are problematic. The
|
|
similarities come about because programmers—<wbr></wbr>physically or
|
|
mentally—<wbr></wbr>copy code. When programmers are confronted with a problem that
|
|
is roughly like another one, they copy the solution and modify the new
|
|
copy to solve the new problem. You will find this behavior both in
|
|
“real” programming contexts as well as in the world of spreadsheets and
|
|
mathematical modeling. Copying code, however, means that programmers copy
|
|
mistakes, and the same fix may have to be applied to many copies. It also
|
|
means that when the underlying data definition is revised or extended, all
|
|
copies of code must be found and modified in a corresponding way. This
|
|
process is both expensive and error-prone, imposing unnecessary costs on
|
|
programming teams.</p><p>Good programmers try to eliminate similarities as much as the programming
|
|
language allows.<span class="refelem"><span class="refcolumn"><span class="refcontent">A program is like an essay. The first
|
|
version is a draft, and drafts demand editing.</span></span></span> “Eliminate” implies that
|
|
programmers write down their first drafts of programs, spot similarities
|
|
(and other problems), and get rid of them. For the last step, they either
|
|
<span style="font-style: italic">abstract</span> or use existing (abstract) functions. It often takes
|
|
several iterations of this process to get the program into satisfactory
|
|
shape.</p><p>The first half of this part shows how to abstract over similarities in
|
|
functions and data definitions. Programmers also refer to the result of
|
|
this process as an <span style="font-style: italic">abstraction</span>, conflating the name of the
|
|
process and its result. The second half is about the use of existing
|
|
abstractions and new language elements to facilitate this process. While
|
|
the examples in this part are taken from the realm of lists, the ideas are
|
|
universally applicable.</p><h3>14<tt> </tt><a name="(part._ch~3add-similarities)"></a>Similarities Everywhere</h3><p>If you solved (some of) the exercises in <a href="part_two.html" data-pltdoc="x">Arbitrarily Large Data</a>, you know that
|
|
many solutions look alike. As a matter of fact, the similarities may tempt
|
|
you to copy the solution of one problem to create the solution for the
|
|
next. But <span class="emph">thou shall not steal code</span>, not even your own. Instead,
|
|
you must <span style="font-style: italic">abstract</span> over similar pieces of code and this chapter
|
|
teaches you how to abstract.</p><p>Our means of avoiding similarities are specific to “Intermediate Student Language”
|
|
or ISL for short.<span class="refelem"><span class="refcolumn"><span class="refcontent">In DrRacket, choose
|
|
“Intermediate Student” from the “How to Design Programs”
|
|
submenu in the “Language” menu.</span></span></span> Almost all other programming languages
|
|
provide similar means; in object-oriented languages you may find
|
|
additional abstraction mechanisms. Regardless, these mechanisms share the
|
|
basic characteristics spelled out in this chapter, and thus the design
|
|
ideas explained here apply in other contexts, too.</p><h4>14.1<tt> </tt><a name="(part._sec~3aprog-similarities)"></a>Similarities in Functions</h4><p>The <a name="(idx._(gentag._362))"></a>design recipe determines a function’s basic organization because the
|
|
<a name="(idx._(gentag._363))"></a>template is created from the data definition without regard to the purpose
|
|
of the function. Not surprisingly, then, functions that consume the same
|
|
kind of data look alike.</p><p><div class="SIntrapara"><a name="(idx._(gentag._364))"></a>
|
|
<a name="(idx._(gentag._365))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Leftfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">does </span><span class="RktSym">l</span><span class="RktCmt"> contain </span><span class="RktVal">"dog"</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-dog?</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktVal">"dog"</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-dog?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">does </span><span class="RktSym">l</span><span class="RktCmt"> contain </span><span class="RktVal">"cat"</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-cat?</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktVal">"cat"</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-cat?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acmp-dog-cat))" x-target-lift="Figure"></a>Figure 86: </span>Two similar functions</span></p></blockquote></div><div class="SIntrapara">Consider the two functions in <a href="part_three.html#%28counter._%28figure._fig~3acmp-dog-cat%29%29" data-pltdoc="x">figure <span class="FigureRef">86</span></a>, which consume
|
|
lists of strings and look for specific strings. The
|
|
function on the left looks for <span class="RktVal">"dog"</span>, the one on the right for
|
|
<span class="RktVal">"cat"</span>. The two functions are nearly indistinguishable. Each
|
|
consumes lists of strings; each function body consists of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
|
|
expression with two clauses. Each produces <span class="RktVal">#false</span> if the input is
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>; each uses an <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span> expression to determine whether
|
|
the first item is the desired item and, if not, uses recursion to look in
|
|
the rest of the list. The only difference is the string that is used in
|
|
the comparison of the nested <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expressions:
|
|
<span class="RktSym">contains-dog?</span> uses <span class="RktVal">"dog"</span> and <span class="RktSym">contains-cat?</span>
|
|
uses <span class="RktVal">"cat"</span>. To highlight the differences, the two strings are
|
|
shaded.</div></p><p><div class="SIntrapara">Good programmers are too lazy to define several closely related
|
|
functions. Instead they define a single function that can look for both a
|
|
<span class="RktVal">"dog"</span> and a <span class="RktVal">"cat"</span> in a list of strings. This general
|
|
function consumes an additional piece of data—<wbr></wbr>the string to
|
|
look for—<wbr></wbr>and is otherwise just like the two original functions:<a name="(idx._(gentag._366))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktSym">l</span><span class="RktCmt"> contains the string </span><span class="RktSym">s</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="hspace"> </span><span class="RktSym">s</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">s</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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">If you really needed a function such as <span class="RktSym">contains-dog?</span> now, you
|
|
could define it as a one-line function, and the same is true for the
|
|
<span class="RktSym">contains-cat?</span> function. <a href="part_three.html#%28counter._%28figure._fig~3acmp-dog-cat2%29%29" data-pltdoc="x">Figure <span class="FigureRef">87</span></a> does just
|
|
that, and you should briefly compare it with <a href="part_three.html#%28counter._%28figure._fig~3acmp-dog-cat%29%29" data-pltdoc="x">figure <span class="FigureRef">86</span></a> to
|
|
make sure you understand how we get from there to here. Best of all, though,
|
|
with <span class="RktSym">contains?</span> it is now trivial to look for <span class="emph">any</span> string in a
|
|
list of strings and there is no need to ever define a specialized function
|
|
such as <span class="RktSym">contains-dog?</span> again.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._367))"></a>
|
|
<a name="(idx._(gentag._368))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">does </span><span class="RktSym">l</span><span class="RktCmt"> contain </span><span class="RktVal">"dog"</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-dog?</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">contains?</span><span class="hspace"> </span><span class="RktVal">"dog"</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">does </span><span class="RktSym">l</span><span class="RktCmt"> contain </span><span class="RktVal">"cat"</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-cat?</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">contains?</span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acmp-dog-cat2))" x-target-lift="Figure"></a>Figure 87: </span>Two similar functions, revisited</span></p></blockquote></div></p><p>What you have<span class="refelem"><span class="refcolumn"><span class="refcontent">Computer scientists borrow the term “abstract”
|
|
from mathematics. There, “6” is an abstract concept because it
|
|
represents <span style="font-weight: bold">all</span> ways of enumerating six things. In contrast, “6
|
|
inches” or “6 eggs” are concrete uses.</span></span></span> just witnessed is called
|
|
<span style="font-style: italic">abstraction</span> or, more precisely, <span style="font-style: italic">functional
|
|
abstraction</span>. Abstracting different versions of functions is one way to
|
|
eliminate similarities from programs, and as you will see, removing
|
|
similarities simplifies keeping a program intact over a long period.</p><p><a name="(counter._(exercise._ex~3acontains-general))"></a><span style="font-weight: bold">Exercise</span> 235. Use the <span class="RktSym">contains?</span> function to
|
|
define functions that search for <span class="RktVal">"atom"</span>, <span class="RktVal">"basic"</span>, and
|
|
<span class="RktVal">"zoo"</span>, respectively. <a href="part_three.html#%28counter._%28exercise._ex~3acontains-general%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3acontains-general2))"></a><span style="font-weight: bold">Exercise</span> 236. Create test suites for the following two
|
|
functions: <a name="(idx._(gentag._369))"></a> <a name="(idx._(gentag._370))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds </span><span class="RktVal">1</span><span class="RktCmt"> to each item on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add1*</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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">add1*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds </span><span class="RktVal">5</span><span class="RktCmt"> to each item on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">plus5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">plus5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr></table></blockquote></div><div class="SIntrapara">Then abstract over them. Define the above two functions in terms of the
|
|
abstraction as one-liners and use the existing <a name="(idx._(gentag._371))"></a>test suites to confirm that
|
|
the revised definitions work properly. Finally, design a function that
|
|
subtracts 2 from each number on a given list. <a href="part_three.html#%28counter._%28exercise._ex~3acontains-general2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>14.2<tt> </tt><a name="(part._sec~3afunc-similarities)"></a>Different Similarities</h4><p>Abstraction looks easy in the case of the <span class="RktSym">contains-dog?</span> and
|
|
<span class="RktSym">contains-cat?</span> functions. It takes only a comparison of two function
|
|
definitions, a replacement of a literal string with a function parameter,
|
|
and a quick check that it is easy to define the old functions with the
|
|
abstract function. This kind of abstraction is so natural that it showed up
|
|
in the preceding two parts of the book without much ado.</p><p>This section illustrates how the very same principle yields a powerful form
|
|
of abstraction. Take a look at <a href="part_three.html#%28counter._%28figure._fig~3acmp-above-below%29%29" data-pltdoc="x">figure <span class="FigureRef">88</span></a>. Both
|
|
functions consume a list of numbers and a threshold. The left one produces
|
|
a list of all those numbers that are below the threshold, while the one on
|
|
the right produces all those that are above the threshold.</p><p><div class="SIntrapara"><a name="(idx._(gentag._372))"></a>
|
|
<a name="(idx._(gentag._373))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">select those numbers on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">that are below </span><span class="RktSym">t</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">small</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">select those numbers on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">that are above </span><span class="RktSym">t</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">large</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">large</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">large</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acmp-above-below))" x-target-lift="Figure"></a>Figure 88: </span>Two more similar functions</span></p></blockquote></div></p><p>The two functions differ in only one place: the comparison operator that
|
|
determines whether a number from the given list should be a part of the
|
|
result or not. The function on the left uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span>, and the right one
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span>. Other than that, the two functions look identical, not
|
|
counting the function name.</p><p>Let’s follow the first example and abstract over the two functions with an
|
|
additional parameter. This time the additional parameter represents a
|
|
comparison operator rather than a string:</p><p><div class="SIntrapara"><a name="(idx._(gentag._374))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">R</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">R</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">extract</span><span class="hspace"> </span><span class="RktSym">R</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">R</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</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">To apply this new function, we must supply three arguments: a function
|
|
<span class="RktSym">R</span> that compares two numbers, a list <span class="RktSym">l</span> of numbers, and a
|
|
threshold <span class="RktSym">t</span>. The function then extracts all those items
|
|
<span class="RktSym">i</span> from <span class="RktSym">l</span> for which <span class="RktPn">(</span><span class="RktSym">R</span><span class="stt"> </span><span class="RktSym">i</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> evaluates to
|
|
<span class="RktVal">#true</span>.</div></p><p>Stop! At this point you should ask whether this definition makes any
|
|
sense. Without further fuss, we have created a function that consumes a
|
|
function—<wbr></wbr>something that you probably have not seen
|
|
before.<span class="refelem"><span class="refcolumn"><span class="refcontent">If you have taken a calculus course, you have encountered
|
|
the differential operator and the indefinite integral. Both of those are
|
|
functions that consume and produce functions. But we do not assume that
|
|
you have taken a calculus course.</span></span></span>
|
|
It turns out, however, that your simple little teaching language ISL
|
|
supports these kinds of functions, and that defining such functions is one
|
|
of the most powerful tools of good programmers—<wbr></wbr>even in languages in which
|
|
function-consuming functions do not seem to be available.</p><p><div class="SIntrapara">Testing shows that <span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> computes the same result as
|
|
<span class="RktPn">(</span><span class="RktSym">small</span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></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">6</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small</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">6</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Similarly, <span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> produces the same result as
|
|
<span class="RktPn">(</span><span class="RktSym">large</span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span>, which means that you can define the two original
|
|
functions like this: <a name="(idx._(gentag._375))"></a> <a name="(idx._(gentag._376))"></a>
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">small-1</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">large-1</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The important insight is <span style="font-weight: bold">not</span> that <span class="RktSym">small-1</span> and
|
|
<span class="RktSym">large-1</span> are one-line definitions. Once you have an abstract
|
|
function such as <span class="RktSym">extract</span>, you can put it to good uses
|
|
elsewhere:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span>: This expression extracts all those
|
|
numbers in <span class="RktSym">l</span> that are equal to <span class="RktSym">t</span>.</p></li><li><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span>: This one produces the list of numbers
|
|
in <span class="RktSym">l</span> that are less than or equal to <span class="RktSym">t</span>.</p></li><li><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e~3d%29%29" class="RktValLink" data-pltdoc="x">>=</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span>: This last expression computes the list
|
|
of numbers that are greater than or equal to the threshold.</p></li></ol></div></p><p><div class="SIntrapara">As a matter of fact, the first argument for <span class="RktSym">extract</span> need not be
|
|
one of ISL’s pre-defined operations. Instead, you can use any function
|
|
that consumes two arguments and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>. Consider this
|
|
example: <a name="(idx._(gentag._377))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is the area of a square with side </span><span class="RktSym">x</span><span class="RktCmt"> larger than </span><span class="RktSym">c</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">That is, <span class="RktSym">squared>?</span> checks whether the claim <span style="font-style: italic">x</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"> > c</span> holds, and it
|
|
is usable with <span class="RktSym">extract</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">This application extracts those numbers in <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span> whose
|
|
square is larger than <span class="RktVal">10</span>.</div></p><p><a name="(counter._(exercise._ex~3asquared))"></a><span style="font-weight: bold">Exercise</span> 237. Evaluate <span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span> and
|
|
<span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span> in DrRacket. How about <span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span>? <a href="part_three.html#%28counter._%28exercise._ex~3asquared%29%29" class="ex-end" data-pltdoc="x"></a></p><p>So far you have seen that abstracted function definitions can be more
|
|
useful than the original functions. For example, <span class="RktSym">contains?</span> is
|
|
more useful than <span class="RktSym">contains-dog?</span> and <span class="RktSym">contains-cat?</span>, and
|
|
<span class="RktSym">extract</span> is more useful than <span class="RktSym">small</span> and
|
|
<span class="RktSym">large</span>.<span class="refelem"><span class="refcolumn"><span class="refcontent">These benefits of abstraction are available at
|
|
all levels of programming: word documents, spreadsheets, small apps, and
|
|
large industrial projects. Creating abstractions for the latter drives
|
|
research on programming languages and software engineering.</span></span></span> Another
|
|
important aspect of abstraction is that you now have a single point of
|
|
control over all these functions. If it turns out that the abstract
|
|
function contains a mistake, fixing its definition suffices to fix all
|
|
other definitions. Similarly, if you figure out how to accelerate the
|
|
computations of the abstract function or how to reduce its energy
|
|
consumption, then all functions defined in terms of this function are
|
|
improved without any extra effort. The following exercises indicate how these
|
|
single-point-of-control improvements work.</p><p><div class="SIntrapara"><a name="(idx._(gentag._378))"></a>
|
|
<a name="(idx._(gentag._379))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._nelon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Nelon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines the smallest </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">number on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._nelon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Nelon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines the largest </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">number on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sup</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">sup</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">sup</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex-abs-min-max))" x-target-lift="Figure"></a>Figure 89: </span>Finding the <span class="RktSym">inf</span> and <span class="RktSym">sup</span> in a list of numbers</span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3aabs-min-max))"></a><span style="font-weight: bold">Exercise</span> 238. Abstract the two functions in
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aex-abs-min-max%29%29" data-pltdoc="x">figure <span class="FigureRef">89</span></a> into a single function. Both consume
|
|
non-empty lists of numbers (<a name="(tech._nelon)"></a><span style="font-style: italic">Nelon</span>) and produce a single number.
|
|
The left one produces the smallest number in the list, and the right one the
|
|
largest.</p><p><div class="SIntrapara">Define <span class="RktSym">inf-1</span> and <span class="RktSym">sup-1</span> in terms of the abstract
|
|
function. Test them with these two lists:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">25</span><span class="hspace"> </span><span class="RktVal">24</span><span class="hspace"> </span><span class="RktVal">23</span><span class="hspace"> </span><span class="RktVal">22</span><span class="hspace"> </span><span class="RktVal">21</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">19</span><span class="hspace"> </span><span class="RktVal">18</span><span class="hspace"> </span><span class="RktVal">17</span><span class="hspace"> </span><span class="RktVal">16</span><span class="hspace"> </span><span class="RktVal">15</span><span class="hspace"> </span><span class="RktVal">14</span><span class="hspace"> </span><span class="RktVal">13</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">11</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">11</span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">13</span><span class="hspace"> </span><span class="RktVal">14</span><span class="hspace"> </span><span class="RktVal">15</span><span class="hspace"> </span><span class="RktVal">16</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">17</span><span class="hspace"> </span><span class="RktVal">18</span><span class="hspace"> </span><span class="RktVal">19</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">21</span><span class="hspace"> </span><span class="RktVal">22</span><span class="hspace"> </span><span class="RktVal">23</span><span class="hspace"> </span><span class="RktVal">24</span><span class="hspace"> </span><span class="RktVal">25</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Why are these functions slow on some of the long lists?</div></p><p>Modify the original functions with the use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._max%29%29" class="RktValLink" data-pltdoc="x">max</a></span>, which picks the
|
|
larger of two numbers, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._min%29%29" class="RktValLink" data-pltdoc="x">min</a></span>, which picks the smaller one. Then
|
|
abstract again, define <span class="RktSym">inf-2</span> and <span class="RktSym">sup-2</span>, and test them
|
|
with the same inputs again. Why are these versions so much faster?</p><p>For another answer to these questions, see <a href="part_three.html#%28part._sec~3alocal-definitions%29" data-pltdoc="x">Local Definitions</a>. <a href="part_three.html#%28counter._%28exercise._ex~3aabs-min-max%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>14.3<tt> </tt><a name="(part._sim-dd._sec~3add-similarities)"></a>Similarities in Data Definitions</h4><p><div class="SIntrapara">Now take a close look at the following two data definitions:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._sim-dd._lon)"></a><span style="font-style: italic">Lon</span><span class="RktCmt"> (</span><a name="(tech._sim-dd._list._of._number)"></a><span style="font-style: italic">List-of-numbers</span><span class="RktCmt">) </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></span><span class="stt"> </span><a href="part_three.html#%28tech._sim-dd._lon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lon</span></a><span class="RktPn">)</span><span class="RktCmt"> </span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._sim-dd._lo)"></a><span style="font-style: italic">Los</span><span class="RktCmt"> (</span><a name="(tech._sim-dd._list._of._string)"></a><span style="font-style: italic">List-of-String</span><span class="RktCmt">) </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></span><span class="stt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="RktPn">)</span><span class="hspace"> </span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">The one on the left introduces lists of numbers; the one on the right
|
|
describes lists of strings. And the two data definitions are
|
|
similar. Like similar functions, the two data definitions use two
|
|
different names, but this is irrelevant because any name would do. The
|
|
only real difference concerns the first position inside of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>
|
|
in the second clause, which specifies what kind of items the list
|
|
contains.</div></p><p><div class="SIntrapara">In order to abstract over this one difference, we proceed as if a data
|
|
definition were a function. We introduce a parameter, which
|
|
makes the data definition look like a function, and where there used to be
|
|
different references, we use this parameter:
|
|
</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">A [</span><a name="(tech._sim-dd._list._of)"></a><span style="font-style: italic">List-of</span><span class="RktCmt"> ITEM] is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="highlighted"><span class="RktSym">ITEM</span></span><span class="stt"> </span><span class="RktPn">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="stt"> </span><span class="RktSym">ITEM</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We call such abstract data definitions <span style="font-style: italic">parametric data
|
|
definitions</span> because of the parameter. Roughly speaking, a parametric
|
|
data definition abstracts from a reference to a particular collection of
|
|
data in the same manner as a function abstracts from a particular
|
|
value.</div></p><p><div class="SIntrapara">The question is, of course, what these parameters range over. For a
|
|
function, they stand for an unknown value; when the function is applied,
|
|
the value becomes known. For a parametric data definition, a parameter
|
|
stands for an entire class of values. The process of supplying the name of
|
|
a data collection to a parametric data definition is called
|
|
<span style="font-style: italic">instantiation</span>; here are some sample instantiations of
|
|
the <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> abstraction:
|
|
</div><div class="SIntrapara"><ul><li><p>When we write [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>], we are saying that
|
|
<span class="RktSym">ITEM</span> represents all numbers so it is just another name
|
|
for <a href="part_three.html#%28tech._sim-dd._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>;</p></li><li><p>Similarly, [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>] defines the same class of
|
|
data as <a href="part_three.html#%28tech._sim-dd._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-String</span></a>; and</p></li><li><p><div class="SIntrapara">If we had identified a class of inventory records, like this:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">IR</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">price</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._sim-dd._ir)"></a><span style="font-style: italic">IR</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="stt"> </span><span class="RktSym">String</span><span class="stt"> </span><span class="RktSym">Number</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">then [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_three.html#%28tech._sim-dd._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>] would be a name for the lists of
|
|
inventory records.</div></p></li></ul></div><div class="SIntrapara">By convention, we use names with all capital letters for parameters of
|
|
data definitions, while the arguments are spelled as needed.</div></p><p><div class="SIntrapara">Our way to validate that these short-hands really mean what we say they mean
|
|
is to substitute the actual name of a data definition, for example,
|
|
<a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>, for the parameter <span class="RktSym">ITEM</span> of the data definition and
|
|
to use a plain name for the data definition:
|
|
</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">A </span><span style="font-style: italic">List-of-numbers-again</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="stt"> </span><span style="font-style: italic">List-of-numbers-again</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since the data definition is self-referential, we copied the entire data
|
|
definition. The resulting definition looks exactly like the conventional
|
|
one for lists of numbers and truly identifies the same class of data.</div></p><p><div class="SIntrapara">Let’s take a brief look at a second example, starting with a structure type
|
|
definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">point</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">hori</span><span class="hspace"> </span><span class="RktSym">veri</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here are two different data definitions that use this structure type:
|
|
</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">A </span><a name="(tech._sim-dd._pair._boolean._string)"></a><span style="font-style: italic">Pair-boolean-string</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-point</span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></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">A </span><a name="(tech._sim-dd._pair._number._image)"></a><span style="font-style: italic">Pair-number-image</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-point</span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></span><span class="stt"> </span><span class="highlighted"><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In this case, the data definitions differ in two places—<wbr></wbr>both marked by
|
|
highlighting. The differences in the <span class="RktSym">hori</span> fields correspond to
|
|
each other, and so do the differences in the <span class="RktSym">veri</span> fields. It is
|
|
thus necessary to introduce two parameters to create an abstract data
|
|
definition:
|
|
</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">A [</span><a name="(tech._sim-dd._cp)"></a><span style="font-style: italic">CP</span><span class="RktCmt"> H V] is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-point</span><span class="stt"> </span><span class="highlighted"><span class="RktSym">H</span></span><span class="stt"> </span><span class="highlighted"><span class="RktSym">V</span></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Here <span class="RktSym">H</span> is the parameter for data collections for the
|
|
<span class="RktSym">hori</span> field, and <span class="RktSym">V</span> stands for data collections that can
|
|
show up in the <span class="RktSym">veri</span> field.</div></p><p>To instantiate a data definition with two parameters, you need two names of
|
|
data collections. Using <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> and <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a> for the parameters
|
|
of <a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a>, you get [<a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a> <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>], which
|
|
describes the collections of <span class="RktSym">point</span>s that combine a number with an
|
|
image. In contrast [<a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a> <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>] combines
|
|
Boolean values with strings in a <span class="RktSym">point</span> structure.</p><p><div class="SIntrapara"><a name="(counter._sim-dd._(exercise._ex~3adef-list))"></a><span style="font-weight: bold">Exercise</span> 239. A list of two items is another frequently used
|
|
form of data in ISL programming. Here is a data definition with two
|
|
parameters:
|
|
</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">A [</span><a name="(tech._sim-dd._list)"></a><span style="font-style: italic">List</span><span class="RktCmt"> X Y] is a list: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="highlighted"><span class="RktSym">X</span></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="highlighted"><span class="RktSym">Y</span></span><span class="stt"> </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">Instantiate this definition to describe the following classes of data:
|
|
</div><div class="SIntrapara"><ul><li><p>pairs of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>s,</p></li><li><p>pairs of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>s and <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s, and</p></li><li><p>pairs of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s and <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s.</p></li></ul></div><div class="SIntrapara">Also make one concrete example for each of these three data definitions. <a href="part_three.html#%28counter._sim-dd._%28exercise._ex~3adef-list%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">Once you have parametric data definitions, you can mix and match them
|
|
to great effect. Consider this one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">]]</span></p></blockquote></div><div class="SIntrapara">The outermost notation is [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> ...], which means
|
|
that you are dealing with a list. The question is what kind of data the list
|
|
contains, and to answer that question, you need to study the inside of the
|
|
<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> expression:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">]</span></p></blockquote></div><div class="SIntrapara">This inner part combines <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> and <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a> in a <span class="RktSym">point</span>. By implication,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">]]</span></p></blockquote></div><div class="SIntrapara">is a list of <span class="RktSym">point</span>s that combine <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s and
|
|
<a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>s. Similarly,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">]]</span></p></blockquote></div><div class="SIntrapara">is an instantiation of <a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a> that combines one <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> with a
|
|
list of <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>s.</div></p><p><div class="SIntrapara"><a name="(counter._sim-dd._(exercise._ex~3anested-dd))"></a><span style="font-weight: bold">Exercise</span> 240. Here are two strange but similar data
|
|
definitions:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._sim-dd._lstr)"></a><span style="font-style: italic">LStr</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="stt"> </span><a href="part_three.html#%28tech._sim-dd._lstr%29" class="techoutside" data-pltdoc="x"><span class="techinside">LStr</span></a><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._sim-dd._lnum)"></a><span style="font-style: italic">LNum</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="stt"> </span><a href="part_three.html#%28tech._sim-dd._lnum%29" class="techoutside" data-pltdoc="x"><span class="techinside">LNum</span></a><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">Both data definitions rely on this structure-type definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">layer</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">stuff</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Both define nested forms of data: one is about numbers and the other about
|
|
strings. Make examples for both. Abstract over the two. Then instantiate
|
|
the abstract definition to get back the originals. <a href="part_three.html#%28counter._sim-dd._%28exercise._ex~3anested-dd%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._sim-dd._(exercise._ex~3anelist-of))"></a><span style="font-weight: bold">Exercise</span> 241. Compare the definitions for
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a> and <a href="part_two.html#%28tech._nelist._of._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-Booleans</span></a>. Then formulate
|
|
an abstract data definition <a name="(tech._sim-dd._nelist._of)"></a><span style="font-style: italic">NEList-of</span>. <a href="part_three.html#%28counter._sim-dd._%28exercise._ex~3anelist-of%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._sim-dd._(exercise._ex~3amaybe))"></a><span style="font-weight: bold">Exercise</span> 242. Here is one more parametric data definition:
|
|
</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">A [</span><a name="(tech._sim-dd._maybe)"></a><span style="font-style: italic">Maybe</span><span class="RktCmt"> X] is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">#false</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktCmt">X</span></td></tr></table></blockquote></div><div class="SIntrapara">Interpret these data definitions:
|
|
[<a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>],
|
|
[<a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a> [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>]],
|
|
and
|
|
[<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> [<a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>]].</div></p><p><div class="SIntrapara">What does the following function signature mean: <a name="(idx._sim-dd._(gentag._380._sim-dd))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">returns the remainder of </span><span class="RktSym">los</span><span class="RktCmt"> starting with </span><span class="RktSym">s</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktVal">#false</span><span class="RktCmt"> otherwise </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">occurs</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">"e"</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">occurs</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">occurs</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Work through the remaining steps of the design recipe. <a href="part_three.html#%28counter._sim-dd._%28exercise._ex~3amaybe%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>14.4<tt> </tt><a name="(part._sec~3afunctions-as-values)"></a>Functions Are Values</h4><p>The functions in this part stretch our understanding of program
|
|
evaluation. It is easy to understand how functions consume more than
|
|
numbers, say strings or images. Structures and lists are a bit of a
|
|
stretch, but they are finite “things” in the end. Function-consuming
|
|
functions, however, are strange. Indeed, the very idea violates the first
|
|
intermezzo in two ways: (1) the names of primitives and
|
|
functions are used as arguments in applications, and (2) parameters are
|
|
used in the function position of applications.</p><p>Spelling out the problem tells you how the ISL grammar differs from BSL’s.
|
|
First, our expression language should include the names of functions and
|
|
primitive operations in the definition. Second, the first position in an
|
|
application should allow things other than function names and primitive
|
|
operations; at a minimum, it must allow variables and function parameters.</p><p>The changes to the grammar seem to demand changes to the evaluation rules,
|
|
but all that changes is the set of values. Specifically, to
|
|
accommodate functions as arguments of functions, the simplest change is to
|
|
say that functions and primitive operations <span style="font-weight: bold">are</span> values.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asem-funcs))"></a><span style="font-weight: bold">Exercise</span> 243. Assume the definitions area in DrRacket contains
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Identify the values among the following expressions:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">f</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">10</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="stt"> </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></p></li></ol></div><div class="SIntrapara">Explain why they are (not) values. <a href="part_three.html#%28counter._%28exercise._ex~3asem-funcs%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asyn-funcs))"></a><span style="font-weight: bold">Exercise</span> 244. Argue why the following sentences are now legal:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktSym">y</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">b</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Explain your reasoning. <a href="part_three.html#%28counter._%28exercise._ex~3asyn-funcs%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3asem2-funcs))"></a><span style="font-weight: bold">Exercise</span> 245. Develop the
|
|
<span class="RktSym">function=at-1.2-3-and-5.775?</span> function.
|
|
Given two functions from numbers to numbers, the function determines
|
|
whether the two produce the same results for <span class="RktVal">1.2</span>, <span class="RktVal">3</span>, and
|
|
<span class="RktVal"><span class="nobreak">-5</span>.775</span>.</p><p>Mathematicians say that two functions are equal if they compute the same
|
|
result when given the same input—<wbr></wbr>for all possible inputs.</p><p>Can we hope to define <span class="RktSym">function=?</span>, which determines whether two
|
|
functions from numbers to numbers are equal? If so, define the function.
|
|
If not, explain why and consider the implication that you have encountered
|
|
the first easily definable idea for which you cannot define a function. <a href="part_three.html#%28counter._%28exercise._ex~3asem2-funcs%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>14.5<tt> </tt><a name="(part._sec~3aeval-ho)"></a>Computing with Functions</h4><p>The switch from BSL+ to ISL allows the use of functions as arguments
|
|
and the use of names in the first position of an application. DrRacket deals
|
|
with names in these positions like anywhere else, but naturally, it expects
|
|
a function as a result. Surprisingly, a simple adaptation of the laws of
|
|
algebra suffices to evaluate programs in ISL.</p><p><div class="SIntrapara">Let’s see how this works for <span class="RktSym">extract</span> from
|
|
<a href="part_three.html#%28part._sec~3afunc-similarities%29" data-pltdoc="x">Different Similarities</a>. Obviously,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">holds. We can use the law of substitution from
|
|
<a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a> and continue computing with the body of the function.
|
|
Like so many times, the parameters, <span class="RktSym">R</span>, <span class="RktSym">l</span>, and <span class="RktSym">t</span>,
|
|
are replaced by their arguments, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span>, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, and <span class="RktVal">5</span>,
|
|
respectively. From here, it is plain arithmetic, starting with the
|
|
conditionals:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></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="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</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="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktPn">[</span><span class="RktVal">#true</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</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="RktSym">==</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Next we look at a one-item list:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The result should be <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> because the only item of this
|
|
list is <span class="RktVal">4</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span> is true. Here is the first step of
|
|
the evaluation:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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">Again, all occurrences of <span class="RktSym">R</span> are replaced by <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span>, <span class="RktSym">l</span>
|
|
by <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>, and <span class="RktSym">t</span> by <span class="RktVal">5</span>. The rest is straightforward:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></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="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktVal">#false</span></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="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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="hspace"> </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This is the key step, with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span> used after being
|
|
substituted into this position. And it continues with arithmetic:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktVal">#true</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The last step is the equation from above, meaning we can apply the law of
|
|
substituting equals for equals.</div></p><p><div class="SIntrapara">Our final example is an application of <span class="RktSym">extract</span> to a list of two items:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Step 1 is new. It deals with the case that <span class="RktSym">extract</span> eliminates the
|
|
first item on the list if it is not below the threshold.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afilter-eval1))"></a><span style="font-weight: bold">Exercise</span> 246. Check step 1 of the last calculation
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</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="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">using DrRacket’s stepper. <a href="part_three.html#%28counter._%28exercise._ex~3afilter-eval1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3afilter-eval2))"></a><span style="font-weight: bold">Exercise</span> 247. Evaluate <span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">8</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span> with DrRacket’s stepper. <a href="part_three.html#%28counter._%28exercise._ex~3afilter-eval2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3asquared-eval))"></a><span style="font-weight: bold">Exercise</span> 248. Evaluate <span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span> and
|
|
<span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span> in DrRacket’s stepper. <a href="part_three.html#%28counter._%28exercise._ex~3asquared-eval%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Consider this interaction:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 4 5)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Here are some steps as the stepper would show them:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><p><span class="RktPn">(</span><span class="RktSym">extract</span><span class="stt"> </span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span></p></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="right" valign="top"><p>(1)</p></td></tr><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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">squared>?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">10</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="right" valign="top"><p>(2)</p></td></tr><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">squared>?</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">10</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract</span><span class="hspace"> </span><span class="RktSym">squared>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="right" valign="top"><p>(3)</p></td></tr></table></blockquote></div><div class="SIntrapara">Use the stepper to confirm the step from lines (1) to (2). Continue the
|
|
stepping to fill in the gaps between steps (2) and (3). Explain each step
|
|
as the use of a law.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aeval-ho-lambda-shows-up))"></a><span style="font-weight: bold">Exercise</span> 249. Functions are values: arguments,
|
|
results, items in lists. Place the following definitions and expressions
|
|
into DrRacket’s definitions window and use the stepper to find out how running
|
|
this program works:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></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">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktVal">10</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><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The stepper displays functions as <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expressions; see <a href="part_three.html#%28part._ch~3a3lambda%29" data-pltdoc="x">Nameless Functions</a>. <a href="part_three.html#%28counter._%28exercise._ex~3aeval-ho-lambda-shows-up%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h3>15<tt> </tt><a name="(part._ch~3aabstract)"></a>Designing Abstractions</h3><p>In essence, to abstract is to turn something concrete into a parameter. We
|
|
have this several times in the preceding section. To abstract similar
|
|
function definitions, you add parameters that replace concrete values in
|
|
the definition. To abstract similar <a name="(idx._(gentag._381))"></a>data definitions, you create
|
|
parametric data definitions. When you encounter other programming
|
|
languages, you will see that their abstraction mechanisms also require
|
|
the introduction of parameters, though they may not be function
|
|
parameters.</p><h4>15.1<tt> </tt><a name="(part._sec~3adesign-abstract)"></a>Abstractions from Examples</h4><p>When you first learned to add, you worked with concrete examples. Your
|
|
parents probably taught you to use your fingers to add two small numbers.
|
|
Later on, you studied how to add two arbitrary numbers; you were
|
|
introduced to your first kind of abstraction. Much later still, you
|
|
learned to formulate expressions that convert temperatures from Celsius to
|
|
Fahrenheit or calculate the distance that a car travels at a given speed
|
|
and amount of time. In short, you went from very concrete examples
|
|
to abstract relations.</p><p><div class="SIntrapara"><a name="(idx._(gentag._382))"></a>
|
|
<a name="(idx._(gentag._383))"></a>
|
|
<a name="(idx._(gentag._384))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts a list of Celsius </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">temperatures to Fahrenheit </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cf*</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">C2F</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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">cf*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">extracts the names of </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">toys from an inventory</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">i</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">IR-name</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">i</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></td></tr><tr><td valign="top"><p></p></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><p></p></td></tr><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts one Celsius </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">temperature to Fahrenheit </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">C2F</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">9/5</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">32</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">IR</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">price</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._ir)"></a><span style="font-style: italic">IR</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._inventory)"></a><span style="font-style: italic">Inventory</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="stt"> </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aabstract1))" x-target-lift="Figure"></a>Figure 90: </span>A pair of similar functions</span></p></blockquote></div><div class="SIntrapara"><a name="(idx._(gentag._385))"></a>
|
|
<a name="(idx._(gentag._386))"></a>
|
|
<a name="(idx._(gentag._387))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cf*</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">g</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">g</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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">cf*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">g</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">i</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">g</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</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><td><p><span class="hspace"> </span></p></td><td><p></p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">map1</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">k</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">g</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">map1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">map1</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">k</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">g</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">map1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acf*-vs-names))" x-target-lift="Figure"></a>Figure 91: </span>The same two similar functions, abstracted</span></p></blockquote></div></p><p>This section introduces a <a name="(idx._(gentag._388))"></a>design recipe for creating abstractions from
|
|
examples. As the preceding section shows, creating abstractions is
|
|
easy. We leave the difficult part to the next section where we show you
|
|
how to find and use existing abstractions.</p><p><div class="SIntrapara">Recall the essence of <a href="part_three.html#%28part._ch~3add-similarities%29" data-pltdoc="x">Similarities Everywhere</a>. We start from two
|
|
concrete definitions; we compare them; we mark the differences; and then
|
|
we abstract. And that is mostly all there is to creating abstractions:
|
|
</div><div class="SIntrapara"><ol><li><p> Step 1 is
|
|
<span style="font-weight: bold">to compare</span> two items for similarities.</p><p>When you find two function definitions that are almost the
|
|
same except for their names and some
|
|
<span class="emph">values</span><span class="refelem"><span class="refcolumn"><span class="refcontent">The recipe requires a substantial modification for
|
|
abstracting over non-values.</span></span></span> at <span class="emph">analogous</span> places, compare them and mark the
|
|
differences. If the two definitions differ in more than one place, connect
|
|
the corresponding differences with a line.</p><p><a href="part_three.html#%28counter._%28figure._fig~3aabstract1%29%29" data-pltdoc="x">Figure <span class="FigureRef">90</span></a> shows a pair of similar function definitions.
|
|
The two functions apply a function to each item in a list. They differ only
|
|
as to which function they apply to each item. The two highlights emphasize
|
|
this essential difference. They also differ in two inessential ways: the
|
|
names of the functions and the names of the parameters.</p></li><li><p>Next we abstract. To <span style="font-style: italic">abstract</span> means to replace the contents of
|
|
corresponding code highlights with new names and add these names to the
|
|
parameter list. For our running example, we obtain the following pair of
|
|
functions after replacing the differences with <span class="RktSym">g</span>; see
|
|
<a href="part_three.html#%28counter._%28figure._fig~3acf%2A-vs-names%29%29" data-pltdoc="x">figure <span class="FigureRef">91</span></a>. This first change eliminates the essential
|
|
difference. Now each function traverses a list and applies some given
|
|
function to each item.</p><p>The inessential differences—<wbr></wbr>the names of the functions and occasionally
|
|
the names of some parameters—<wbr></wbr>are easy to eliminate. Indeed, if you have
|
|
explored DrRacket, you know that check syntax allows you to do this
|
|
systematically and easily; see bottom of <a href="part_three.html#%28counter._%28figure._fig~3acf%2A-vs-names%29%29" data-pltdoc="x">figure <span class="FigureRef">91</span></a>.
|
|
We choose to use <span class="RktSym">map1</span> for the name of the function and
|
|
<span class="RktSym">k</span> for the name of the list parameter. No matter which names you
|
|
choose, the result is two identical function definitions.</p><p>Our example is simple. In many cases, you will find that there is more than
|
|
just one pair of differences. The key is to find pairs of
|
|
differences. When you mark up the differences with paper and pencil, connect
|
|
related boxes with a line. Then introduce one additional parameter per
|
|
line. And don’t forget to change all recursive uses of the function so
|
|
that the additional parameters go along for the ride.</p></li><li><p>Now we must validate that the new function is a correct abstraction
|
|
of the original pair of functions. To validate means <span style="font-weight: bold">to
|
|
test</span>, which here means to define the two original functions in terms of
|
|
the abstraction.</p><p><div class="SIntrapara">Thus suppose that one original function is called <span class="RktSym">f-original</span> and
|
|
consumes one argument and that the abstract function is called
|
|
<span class="RktSym">abstract</span>. If <span class="RktSym">f-original</span> differs from the other concrete
|
|
function in the use of one value, say, <span class="RktSym">val</span>, the following function
|
|
definition
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f-from-abstract</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">abstract</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">val</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">introduces the function <span class="RktSym">f-from-abstract</span>, which should be
|
|
equivalent to <span class="RktSym">f-original</span>. That is, <span class="RktPn">(</span><span class="RktSym">f-from-abstract</span><span class="stt"> </span><span class="RktSym">V</span><span class="RktPn">)</span> should produce the same answer as
|
|
<span class="RktPn">(</span><span class="RktSym">f-original</span><span class="stt"> </span><span class="RktSym">V</span><span class="RktPn">)</span> for every proper value
|
|
<span class="RktSym">V</span>. In particular, it must hold for all values that your
|
|
tests for <span class="RktSym">f-original</span> use. So reformulate and rerun those tests
|
|
for <span class="RktSym">f-from-abstract</span> and make sure they succeed.</div></p><p><div class="SIntrapara">Let’s return to our running example:<a name="(idx._(gentag._389))"></a> <a name="(idx._(gentag._390))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cf*-from-map1</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">map1</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">C2F</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><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names-from-map1</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">map1</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktSym">IR-name</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">A complete example would include some tests, and thus we can assume that
|
|
both <span class="RktSym">cf*</span> and <span class="RktSym">names</span> come with some tests:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cf*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-4</span>0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">212</span><span class="hspace"> </span><span class="RktVal">32</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-4</span>0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">21.0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">13.0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">To ensure that the functions defined in terms of <span class="RktSym">map1</span> work
|
|
properly, you can copy the tests and change the function names
|
|
appropriately:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cf*-from-map1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-4</span>0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">212</span><span class="hspace"> </span><span class="RktVal">32</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-4</span>0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">names-from-map1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">21.0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">13.0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p></li><li><p>A new abstraction needs <a name="(idx._(gentag._391))"></a><span style="font-weight: bold">a signature</span>, because, as
|
|
<a href="part_three.html#%28part._ch~3a3use%29" data-pltdoc="x">Using Abstractions</a> explains, the reuse of abstractions starts with their
|
|
signatures. Finding useful signatures is a serious problem. For now we
|
|
use the running example to illustrate the difficulty;
|
|
<a href="part_three.html#%28part._sec~3aabs-signatures%29" data-pltdoc="x">Similarities in Signatures</a> resolves the issue.</p><p><div class="SIntrapara">Consider the problem of <span class="RktSym">map1</span>’s signature. On
|
|
the one hand, if you view <span class="RktSym">map1</span> as an abstraction of <span class="RktSym">cf*</span>, you
|
|
might think it is
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> [</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></p></blockquote></div><div class="SIntrapara">that is, the original signature extended with one part for functions:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></p></blockquote></div><div class="SIntrapara">Since the additional parameter for <span class="RktSym">map1</span> is a function, the use of
|
|
a function signature to describe it should not surprise you. This function
|
|
signature is also quite simple; it is a “name” for all the functions
|
|
from numbers to numbers. Here <span class="RktSym">C2F</span> is such a function, and so are
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sin%29%29" class="RktValLink" data-pltdoc="x">sin</a></span>, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._imag-part%29%29" class="RktValLink" data-pltdoc="x">imag-part</a></span>.</div></p><p><div class="SIntrapara">On the other hand, if you view <span class="RktSym">map1</span> as an abstraction of
|
|
<span class="RktSym">names</span>, the signature is quite different:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></p></blockquote></div><div class="SIntrapara">This time the additional parameter is <span class="RktSym">IR-name</span>, which is a
|
|
selector function that consumes <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>s and produces <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s.
|
|
But clearly this second signature would be useless in the first case, and
|
|
vice versa. To accommodate both cases, the signature for <span class="RktSym">map1</span>
|
|
must express that <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>, <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>, and <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> are
|
|
coincidental.</div></p><p>Also concerning signatures, you are probably eager to use <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a>
|
|
by now. It is clearly easier to write [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>]
|
|
than spelling out a data definition for <a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a>. So yes, as of
|
|
now, we use <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> when it is all about lists, and you should
|
|
too.</p></li></ol></div></p><p><div class="SIntrapara">Once you have abstracted two functions, you should check whether there are
|
|
other uses for the abstract function. If so, the abstraction is truly
|
|
useful. Consider <span class="RktSym">map1</span>, for example. It is easy to see how to use
|
|
it to add <span class="RktVal">1</span> to each number on a list of numbers: <a name="(idx._(gentag._392))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add1-to-each</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">map1</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Similarly, <span class="RktSym">map1</span> can also be used to extract the price of each
|
|
item in an inventory. When you can imagine many such uses for a new
|
|
abstraction, add it to a library of useful functions to have around. Of
|
|
course, it is quite likely that someone else has thought of it and the
|
|
function is already a part of the language. For a function like
|
|
<span class="RktSym">map1</span>, see <a href="part_three.html#%28part._ch~3a3use%29" data-pltdoc="x">Using Abstractions</a>.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._393))"></a>
|
|
<a name="(idx._(gentag._394))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">tabulates </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sin%29%29" class="RktValLink" data-pltdoc="x">sin</a></span><span class="RktCmt"> between </span><span class="RktSym">n</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">and </span><span class="RktVal">0</span><span class="RktCmt"> (incl.) in a list</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tab-sin</span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sin%29%29" class="RktValLink" data-pltdoc="x">sin</a></span><span class="hspace"> </span><span class="RktVal">0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sin%29%29" class="RktValLink" data-pltdoc="x">sin</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tab-sin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktSym">n</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></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">tabulates </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqrt%29%29" class="RktValLink" data-pltdoc="x">sqrt</a></span><span class="RktCmt"> between </span><span class="RktSym">n</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">and </span><span class="RktVal">0</span><span class="RktCmt"> (incl.) in a list</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tab-sqrt</span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqrt%29%29" class="RktValLink" data-pltdoc="x">sqrt</a></span><span class="hspace"> </span><span class="RktVal">0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqrt%29%29" class="RktValLink" data-pltdoc="x">sqrt</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tab-sqrt</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktSym">n</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></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3aabs-tabulate))" x-target-lift="Figure"></a>Figure 92: </span>The similar functions for <a href="part_three.html#%28counter._%28exercise._ex~3aabs-tabulate%29%29" data-pltdoc="x">exercise 250</a></span></p></blockquote></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._395))"></a>
|
|
<a name="(idx._(gentag._396))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the sum of </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the numbers on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the product of </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the numbers on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">product</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">product</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3aabs-sum-prod))" x-target-lift="Figure"></a>Figure 93: </span>The similar functions for <a href="part_three.html#%28counter._%28exercise._ex~3aabs-sum-prod%29%29" data-pltdoc="x">exercise 251</a></span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3aabs-tabulate))"></a><span style="font-weight: bold">Exercise</span> 250. Design <span class="RktSym">tabulate</span>, which is the
|
|
abstraction of the two functions in <a href="part_three.html#%28counter._%28figure._fig~3aex~3aabs-tabulate%29%29" data-pltdoc="x">figure <span class="FigureRef">92</span></a>. When
|
|
<span class="RktSym">tabulate</span> is properly designed, use it to define a tabulation
|
|
function for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._tan%29%29" class="RktValLink" data-pltdoc="x">tan</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3aabs-tabulate%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aabs-sum-prod))"></a><span style="font-weight: bold">Exercise</span> 251. Design <span class="RktSym">fold1</span>, which is the
|
|
abstraction of the two functions in <a href="part_three.html#%28counter._%28figure._fig~3aex~3aabs-sum-prod%29%29" data-pltdoc="x">figure <span class="FigureRef">93</span></a>. <a href="part_three.html#%28counter._%28exercise._ex~3aabs-sum-prod%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afold2))"></a><span style="font-weight: bold">Exercise</span> 252. Design <span class="RktSym">fold2</span>, which is the abstraction of
|
|
the two functions in <a href="part_three.html#%28counter._%28figure._fig~3aex~3afold2%29%29" data-pltdoc="x">figure <span class="FigureRef">94</span></a>. Compare this exercise with
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3aabs-sum-prod%29%29" data-pltdoc="x">exercise 251</a>. Even though both involve the <span class="RktSym">product</span>
|
|
function, this exercise poses an additional challenge because the second
|
|
function, <span class="RktSym">image*</span>, consumes a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and produces an
|
|
<a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>. Still, the solution is within reach of the material in this
|
|
section, and it is especially worth comparing the solution with the one to
|
|
the preceding exercise. The comparison yields interesting insights into
|
|
abstract signatures. <a href="part_three.html#%28counter._%28exercise._ex~3afold2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._397))"></a>
|
|
<a name="(idx._(gentag._398))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">product</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">product</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">image*</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">emt</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">place-dot</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">image*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">place-dot</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">img</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">dot</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">img</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">graphical constants:</span><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">emt</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">100</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">dot</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._circle%29%29" class="RktValLink" data-pltdoc="x">circle</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3afold2))" x-target-lift="Figure"></a>Figure 94: </span>The similar functions for <a href="part_three.html#%28counter._%28exercise._ex~3afold2%29%29" data-pltdoc="x">exercise 252</a></span></p></blockquote></div></p><p>Lastly, when you are dealing with data definitions, the abstraction process
|
|
proceeds in an analogous manner. The extra parameters to data definitions
|
|
stand for collections of values, and testing means spelling out a data
|
|
definition for some concrete examples. All in all, abstracting over data
|
|
definitions tends to be easier than abstracting over functions, and so we
|
|
leave it to you to adapt the design recipe appropriately.</p><h4>15.2<tt> </tt><a name="(part._sec~3aabs-signatures)"></a>Similarities in Signatures</h4><p>As it turns out, a <a name="(idx._(gentag._399))"></a>function’s signature is key to its reuse. Hence, you
|
|
must learn to formulate signatures that describe abstracts in their most
|
|
general terms possible. To understand how this works, we start with a
|
|
second look at signatures and from the simple—<wbr></wbr>though possibly
|
|
startling—<wbr></wbr>insight that <a name="(idx._(gentag._400))"></a>signatures are basically <a name="(idx._(gentag._401))"></a>data definitions.</p><p><div class="SIntrapara">Both <a name="(idx._(gentag._402))"></a>signatures and <a name="(idx._(gentag._403))"></a>data definitions specify a class of data; the
|
|
difference is that data definitions also name the class of data while
|
|
signatures don’t. Nevertheless, when you write down
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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">n</span><span class="hspace"> </span><span class="RktSym">b</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"hello world"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">your first line describes an entire class of data, and your second one
|
|
states that <span class="RktSym">f</span> belongs to that class. To be precise, the signature
|
|
describes the class of <span style="font-weight: bold">all functions</span> that consume a <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>
|
|
and a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> and yield a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>.</div></p><p>In general, the arrow notation of <a name="(idx._(gentag._404))"></a>signatures is like the
|
|
<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> notation from <a href="part_three.html#%28part._sim-dd._sec~3add-similarities%29" data-pltdoc="x">Similarities in Data Definitions</a>.
|
|
The latter consumes (the name of) one class of data, say X, and describes
|
|
all lists of <span class="RktCmt">X</span> items—<wbr></wbr>without assigning it a name. The arrow notation
|
|
consumes an arbitrary number of classes of data and describes collections
|
|
of functions.</p><p>What this means is that the <a name="(idx._(gentag._405))"></a>abstraction design recipe applies to
|
|
signatures, too. You compare similar signatures; you highlight the
|
|
differences; and then you replace those with parameters. But the process
|
|
of abstracting signatures feels more complicated than the one for
|
|
functions, partly because signatures are already abstract pieces of the
|
|
design recipe and partly because the arrow-based notation is much more
|
|
complex than anything else we have encountered.</p><p><div class="SIntrapara">Let’s start with the signatures of <span class="RktSym">cf*</span> and <span class="RktSym">names</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -2.53125px; margin: -3px -3px -3px -3px;" src="pict_111.png" alt="image" width="218.818359375" height="74.265625"/></p></blockquote></div><div class="SIntrapara">The diagram is the result of the compare-and-contrast step.
|
|
Comparing the two signatures shows that they differ in two places: to the
|
|
left of the arrow, we see <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> versus <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>, and to its right,
|
|
it is <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> versus <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>.</div></p><p><div class="SIntrapara">If we replace the two differences with some kind of parameters, say <span class="RktCmt">X</span> and
|
|
<span class="RktCmt">Y</span>, we get the same signature:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> Y]</span></p></blockquote></div><div class="SIntrapara">The new signature starts with a sequence of variables, drawing an analogy
|
|
to function definitions and the data definitions above. Roughly speaking,
|
|
these variables are the parameters of the signature, like those of
|
|
functions and data definitions. To make the latter concrete, the variable
|
|
sequence is like <span class="RktCmt">ITEM</span> in the definition of <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> or the <span class="RktCmt">X</span> and <span class="RktCmt">Y</span> in the
|
|
definition of <a href="part_three.html#%28tech._sim-dd._cp%29" class="techoutside" data-pltdoc="x"><span class="techinside">CP</span></a> from <a href="part_three.html#%28part._sim-dd._sec~3add-similarities%29" data-pltdoc="x">Similarities in Data Definitions</a>. And just like those, <span class="RktCmt">X</span> and <span class="RktCmt">Y</span>
|
|
range over classes of values.</div></p><p><div class="SIntrapara">An instantiation of this parameter list is the rest of the signature with
|
|
the parameters replaced by the data collections: either their names or
|
|
other parameters or abbreviations such as <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> from above. Thus, if
|
|
you replace both <span class="RktCmt">X</span> and <span class="RktCmt">Y</span> with <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>, you get back the signature
|
|
for <span class="RktSym">cf*</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></p></blockquote></div><div class="SIntrapara">If you choose <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a> and <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>, you get back the signature for <span class="RktSym">names</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">]</span></p></blockquote></div><div class="SIntrapara">And that explains why we may consider this parametrized signature as
|
|
an abstraction of the original signatures for <span class="RktSym">cf*</span> and
|
|
<span class="RktSym">names</span>.</div></p><p><div class="SIntrapara">Once we add the extra function parameter to these two functions, we get
|
|
<span class="RktSym">map1</span>, and the signatures are as follows:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -2.53125px; margin: -3px -3px -3px -3px;" src="pict_112.png" alt="image" width="348.43359375" height="74.265625"/></p></blockquote></div><div class="SIntrapara">Again, the signatures are in pictorial form and with arrows connecting the
|
|
corresponding differences.
|
|
These markups suggest that the differences in the second argument—<wbr></wbr>a
|
|
function—<wbr></wbr>are related to the differences in the original
|
|
signatures. Specifically, <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> and <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a> on the left of the
|
|
new arrow refer to items on the first argument—<wbr></wbr>a list—<wbr></wbr>and the
|
|
<a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> and <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> on the right refer to the items on the
|
|
result—<wbr></wbr>also a list.</div></p><p>Since listing the parameters of a signature is extra work, for our purposes,
|
|
we simply say that from now on all variables in signatures are parameters.
|
|
Other programming languages, however, insist on explicitly listing the
|
|
parameters of signatures, but in return you can articulate additional
|
|
constraints in such signatures and the signatures are checked before you
|
|
run the program.</p><p><div class="SIntrapara">Now let’s apply the same trick to get a signature for <span class="RktSym">map1</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [X -> Y] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> Y]</span></p></blockquote></div><div class="SIntrapara">Concretely, <span class="RktSym">map1</span> consumes a list of items, all of which belong to
|
|
some (yet to be determined) collection of data called X. It also consumes
|
|
a function that consumes elements of <span class="RktCmt">X</span> and produces elements of a second
|
|
unknown collection, called <span class="RktCmt">Y</span>. The result of <span class="RktSym">map1</span> is lists that
|
|
contain items from <span class="RktCmt">Y</span>.</div></p><p><div class="SIntrapara">Abstracting over <a name="(idx._(gentag._406))"></a>signatures takes practice. Here is a second pair:
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span><span class="hspace"> </span><span class="RktCmt">-> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr></table></blockquote></div><div class="SIntrapara">They are the signatures for <span class="RktSym">product</span> and <span class="RktSym">image*</span> in
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3afold2%29%29" data-pltdoc="x">exercise 252</a>. While the two signatures have some common organization, the
|
|
differences are distinct. Let us first spell out the common organization in
|
|
detail:
|
|
</div><div class="SIntrapara"><ul><li><p>both signatures describe one-argument functions; and</p></li><li><p>both argument descriptions employ the <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> construction.</p></li></ul></div><div class="SIntrapara">In contrast to the first example, here one signature refers to
|
|
<a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> twice while the second one refers to <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and
|
|
<a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>s in analogous positions. A structural comparison shows that
|
|
the first occurrence of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> corresponds to <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and the
|
|
second one to <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>:</div></p><blockquote class="SCentered"><p><img style="vertical-align: -2.53125px; margin: -3px -3px -3px -3px;" src="pict_113.png" alt="image" width="171.814453125" height="74.265625"/></p></blockquote><p><div class="SIntrapara">To make progress on a signature for the abstraction of the two
|
|
functions in <a href="part_three.html#%28counter._%28exercise._ex~3afold2%29%29" data-pltdoc="x">exercise 252</a>, let’s take the first two steps of the
|
|
design recipe: <a name="(idx._(gentag._407))"></a><a name="(idx._(gentag._408))"></a>
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">pr*</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">bs</span><span class="hspace"> </span><span class="RktSym">jn</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">bs</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">jn</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">pr*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">bs</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">jn</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">im*</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">bs</span><span class="hspace"> </span><span class="RktSym">jn</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">bs</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">jn</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">im*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">bs</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">jn</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">Since the two functions differ in two pairs of values, the revised versions
|
|
consume two additional values: one is an atomic value, to be used in the
|
|
base case, and the other one is a function that joins together the result
|
|
of the natural recursion with the first item on the given list.</div></p><p><div class="SIntrapara">The key is to translate this insight into two signatures for the two new
|
|
functions. When you do so for <span class="RktSym">pr*</span>, you get
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> [</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">-> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span></td></tr></table></blockquote></div><div class="SIntrapara">because the result in the base case is a number and because the function
|
|
for the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span>. Similarly, the signature for
|
|
<span class="RktSym">im*</span> is
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> [</span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">-> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr></table></blockquote></div><div class="SIntrapara">As you can see from the function definition for <span class="RktSym">im*</span>, the base
|
|
case returns an image, and the combination function is <span class="RktSym">place-dot</span>,
|
|
which combines a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a> into an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>.</div></p><p><div class="SIntrapara">Now we take the diagram from above and extend it to the signatures with the
|
|
additional inputs:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -2.53125px; margin: -3px -3px -3px -3px;" src="pict_114.png" alt="image" width="397.7578125" height="74.265625"/></p></blockquote></div><div class="SIntrapara">From this diagram, you can easily see that the two revised signatures
|
|
share even more organization than the original two. Furthermore, the pieces
|
|
that describe the base cases correspond to each other and so do the pieces
|
|
of the sub-signature that describe the combination function. All in all
|
|
there are six pairs of differences, but they boil down to just two:
|
|
</div><div class="SIntrapara"><ol><li><p>some occurrences of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> correspond to <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>, and</p></li><li><p>other occurrences of <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> correspond to <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>.</p></li></ol></div><div class="SIntrapara">So to abstract we need two variables, one per kind of correspondence.</div></p><p><div class="SIntrapara">Here then is the signature for <span class="RktSym">fold2</span>, the abstraction from
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3afold2%29%29" data-pltdoc="x">exercise 252</a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] Y [X Y -> Y] -> Y</span></p></blockquote></div><div class="SIntrapara">Stop! Make sure that replacing both parameters of the signature, <span class="RktCmt">X</span> and <span class="RktCmt">Y</span>,
|
|
with <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> yields the signature for <span class="RktSym">pr*</span> and that
|
|
replacing the same variables with <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>,
|
|
respectively, yields the signature for <span class="RktSym">im*</span>.</div></p><p><div class="SIntrapara">The two examples illustrate how to find general signatures. In principle
|
|
the process is just like the one for abstracting functions. Due to the
|
|
informal nature of signatures, however, it cannot be checked with running
|
|
examples the way code is checked. Here is a step-by-step formulation:
|
|
</div><div class="SIntrapara"><ol><li><p>Given two similar function definitions, <span class="RktSym">f</span> and <span class="RktSym">g</span>,
|
|
compare their signatures for similarities and differences. The goal is to
|
|
discover the organization of the signature and to mark the places where one
|
|
signature differs from the other. Connect the differences as pairs just
|
|
like you do when you analyze function bodies.</p></li><li><p>Abstract <span class="RktSym">f</span> and <span class="RktSym">g</span> into <span class="RktSym">f-abs</span> and
|
|
<span class="RktSym">g-abs</span>. That is, add parameters that eliminate the differences
|
|
between <span class="RktSym">f</span> and <span class="RktSym">g</span>. Create signatures for <span class="RktSym">f-abs</span>
|
|
and <span class="RktSym">g-abs</span>. Keep in mind what the new parameters originally stood
|
|
for; this helps you figure out the new pieces of the signatures.</p></li><li><p>Check whether the analysis of step 1 extends to the signatures of
|
|
<span class="RktSym">f-abs</span> and <span class="RktSym">g-abs</span>. If so, replace the differences with
|
|
variables that range over classes of data. Once the two signatures are the
|
|
same, you have a signature for the abstracted function.</p></li><li><p><div class="SIntrapara">Test the abstract signature. First, ensure that suitable
|
|
substitutions of the variables in the abstract signature yield the
|
|
signatures of <span class="RktSym">f-abs</span> and <span class="RktSym">g-abs</span>. Second, check that the
|
|
generalized signature is in sync with the code. For example, if <span class="RktSym">p</span>
|
|
is a new parameter and its signature is
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">... [A B -> C] ...</span></p></blockquote></div><div class="SIntrapara">then <span class="RktSym">p</span> must always be applied to two arguments, the first one
|
|
from A and the second one from B. And the result of an application of
|
|
<span class="RktSym">p</span> is going to be a C and should be used where elements of C are
|
|
expected.</div></p></li></ol></div><div class="SIntrapara">As with abstracting functions, the key is to compare the concrete
|
|
signatures of the examples and to determine the similarities and
|
|
differences. With enough practice and intuition, you will soon be able to
|
|
abstract signatures without much guidance.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aarrows-dd))"></a><span style="font-weight: bold">Exercise</span> 253. Each of these signatures describes a class of functions:
|
|
</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">[</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr></table></blockquote></div><div class="SIntrapara">Describe these collections with at least one example from ISL. <a href="part_three.html#%28counter._%28exercise._ex~3aarrows-dd%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afancy-signatures1))"></a><span style="font-weight: bold">Exercise</span> 254. Formulate signatures for the following
|
|
functions:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">sort-n</span>, which consumes a list of numbers and a function that
|
|
consumes two numbers (from the list) and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>; <span class="RktSym">sort-n</span>
|
|
produces a sorted list of numbers.</p></li><li><p><span class="RktSym">sort-s</span>, which consumes a list of strings and a function that
|
|
consumes two strings (from the list) and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>; <span class="RktSym">sort-s</span>
|
|
produces a sorted list of strings.</p></li></ul></div><div class="SIntrapara">Then abstract over the two signatures, following the above steps. Also
|
|
show that the generalized signature can be instantiated to describe the
|
|
signature of a sort function for lists of <a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a>s. <a href="part_three.html#%28counter._%28exercise._ex~3afancy-signatures1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afancy-signatures2))"></a><span style="font-weight: bold">Exercise</span> 255. Formulate signatures for the following
|
|
functions:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">map-n</span>, which consumes a list of numbers and a function from
|
|
numbers to numbers to produce a list of numbers.</p></li><li><p><span class="RktSym">map-s</span>, which consumes a list of strings and a function from
|
|
strings to strings and produces a list of strings.</p></li></ul></div><div class="SIntrapara">Then abstract over the two signatures, following the above steps. Also
|
|
show that the generalized signature can be instantiated to describe the
|
|
signature of the <span class="RktSym">map1</span> function above. <a href="part_three.html#%28counter._%28exercise._ex~3afancy-signatures2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>15.3<tt> </tt><a name="(part._sec~3aspoc)"></a>Single Point of Control</h4><p>In general, programs are like drafts of papers. Editing drafts is important
|
|
to correct typos, to fix grammatical mistakes, to make the document
|
|
consistent, and to eliminate repetitions. Nobody wants to read papers
|
|
that repeat themselves a lot, and nobody wants to read such programs
|
|
either.</p><p>The elimination of similarities in favor of abstractions has many
|
|
advantages. Creating an abstraction simplifies definitions. It may also
|
|
uncover problems with existing functions, especially when similarities
|
|
aren’t quite right. But, the single most important advantage is the
|
|
creation of <span style="font-style: italic">single points of control</span> for some common
|
|
functionality.</p><p>Putting the definition for some functionality in one place makes it easy to
|
|
maintain a program. When you discover a mistake, you have to go to just
|
|
one place to fix it. When you discover that the code should deal with
|
|
another form of data, you can add the code to just one place. When you
|
|
figure out an improvement, one change improves all uses of the
|
|
functionality. If you had made copies of the functions or code in general,
|
|
you would have to find all copies and fix them; otherwise the mistake
|
|
might live on or only one of the functions would run faster.</p><p><div class="SIntrapara">We therefore formulate this <a name="(idx._(gentag._409))"></a>guideline:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-style: italic">Form an abstraction instead of copying and modifying any code.</span></p></blockquote></div></p><p>Our <a name="(idx._(gentag._410))"></a>design recipe for abstracting
|
|
functions is the most basic tool to create abstractions. To use it
|
|
requires practice. As you practice, you expand your capabilities to read,
|
|
organize, and maintain programs. The best programmers are those who
|
|
actively edit their programs to build new abstractions so that they
|
|
collect things related to a task at a single point. Here we use functional
|
|
abstraction to study this practice; in other courses on programming, you
|
|
will encounter other forms of abstraction, most importantly
|
|
<span style="font-style: italic">inheritance</span> in class-based object-oriented languages.</p><h4>15.4<tt> </tt><a name="(part._sec~3aapriori-abs)"></a>Abstractions from Templates</h4><p>The first two chapters of this part present many functions based on the
|
|
same <a name="(idx._(gentag._411))"></a>template. After all, the design recipe says to organize functions
|
|
around the organization of the (major) input <a name="(idx._(gentag._412))"></a>data definition. It is
|
|
therefore not surprising that many function definitions look similar to
|
|
each other.</p><p><div class="SIntrapara">Indeed, you should abstract from the templates directly, and you should do so
|
|
automatically; some experimental programming languages do so. Even
|
|
though this topic is still a subject of research, you are now in a
|
|
position to understand the basic idea. Consider the template for lists:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fun-for-l</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fun-for-l</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></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 contains two gaps, one in each clause. When you use this template to
|
|
define a list-processing function, you usually fill these gaps with a
|
|
value in the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause and with a function
|
|
<span class="RktSym">combine</span> in the second clause. The <span class="RktSym">combine</span> function
|
|
consumes the first item of the list and the result of the natural
|
|
recursion and creates the result from these two pieces of data.</div></p><p><div class="SIntrapara">Now that you know how to create abstractions, you can complete the
|
|
definition of the abstraction from this informal description: <a name="(idx._(gentag._413))"></a>
|
|
</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">[X Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] Y [X Y -> Y] -> Y</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">reduce</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">base</span><span class="hspace"> </span><span class="RktSym">combine</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">base</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">combine</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></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">reduce</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">base</span><span class="hspace"> </span><span class="RktSym">combine</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 consumes two extra arguments: <span class="RktSym">base</span>, which is the value for the
|
|
base case, and <span class="RktSym">combine</span>, which is the function that performs the
|
|
value combination for the second clause.</div></p><p><div class="SIntrapara">Using <span class="RktSym">reduce</span> you can define many plain list-processing functions as
|
|
“one liners.” Here are definitions for <span class="RktSym">sum</span> and <span class="RktSym">product</span>,
|
|
two functions used several times in the first few sections of this chapter: <a name="(idx._(gentag._414))"></a><a name="(idx._(gentag._415))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">lon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">reduce</span><span class="hspace"> </span><span class="RktSym">lon</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">product</span><span class="hspace"> </span><span class="RktSym">lon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">reduce</span><span class="hspace"> </span><span class="RktSym">lon</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">For <span class="RktSym">sum</span>, the base case always produces <span class="RktVal">0</span>; adding the
|
|
first item and the result of the natural recursion combines the values of
|
|
the second clause. Analogous reasoning explains <span class="RktSym">product</span>.
|
|
Other list-processing functions can be defined in a similar manner using
|
|
<span class="RktSym">reduce</span>.</div></p><h3>16<tt> </tt><a name="(part._ch~3a3use)"></a>Using Abstractions</h3><p>Once you have abstractions, you should use them when possible. They create
|
|
single points of control, and they are a work-saving device. More
|
|
precisely, the use of an abstraction helps <span style="font-weight: bold">readers</span> of your code to
|
|
understand your intentions. If the abstraction is well-known and built
|
|
into the language or comes with its standard libraries, it signals more
|
|
clearly what your function does than custom-designed code.</p><p>This chapter is all about the reuse of existing ISL abstractions. It starts
|
|
with a section on existing ISL abstractions, some of which you have
|
|
seen under false names. The remaining sections are about reusing such
|
|
abstractions. One key ingredient is a new syntactic construct,
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>, for defining functions and variables (and even structure types)
|
|
locally within a function. An auxiliary ingredient, introduced in the last
|
|
section, is the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> construct for creating nameless functions;
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> is a convenience but inessential to the idea of reusing
|
|
abstract functions.</p><p><div class="SIntrapara"><a name="(idx._(gentag._416))"></a>
|
|
<a name="(idx._(gentag._417))"></a>
|
|
<a name="(idx._(gentag._418))"></a>
|
|
<a name="(idx._(gentag._419))"></a>
|
|
<a name="(idx._(gentag._420))"></a>
|
|
<a name="(idx._(gentag._421))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X] </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> [</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">constructs a list by applying </span><span class="RktSym">f</span><span class="RktCmt"> to </span><span class="RktVal">0</span><span class="RktCmt">, </span><span class="RktVal">1</span><span class="RktCmt">, </span>...<span class="RktCmt">, </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">[X] [X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a list from those items on </span><span class="RktSym">lx</span><span class="RktCmt"> for which </span><span class="RktSym">p</span><span class="RktCmt"> holds </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">[X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [X X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a version of </span><span class="RktSym">lx</span><span class="RktCmt"> that is sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace"> </span><span class="RktSym">lx</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">[X Y] [X -> Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> Y]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">constructs a list by applying </span><span class="RktSym">f</span><span class="RktCmt"> to each item on </span><span class="RktSym">lx</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">[X] [X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktSym">p</span><span class="RktCmt"> holds for every item on </span><span class="RktSym">lx</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">[X] [X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktSym">p</span><span class="RktCmt"> holds for at least one item on </span><span class="RktSym">lx</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aisl-ho-list))" x-target-lift="Figure"></a>Figure 95: </span>ISL’s abstract functions for list processing (1)</span></p></blockquote></div></p><h4>16.1<tt> </tt><a name="(part._sec~3aisl-abstractions)"></a>Existing Abstractions</h4><p><div class="SIntrapara">ISL provides a number of abstract functions for processing natural numbers
|
|
and lists. <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">Figure <span class="FigureRef">95</span></a> collects the header material for
|
|
the most important ones. The first one processes natural numbers and builds
|
|
lists:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 1 2 3)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The next three process lists and produce lists:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._odd~3f%29%29" class="RktValLink" data-pltdoc="x">odd?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 1 3 5)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 5 4 3 2 1)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 2 3 3 4 4 4)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">In contrast, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> reduce lists to a
|
|
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._odd~3f%29%29" class="RktValLink" data-pltdoc="x">odd?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._odd~3f%29%29" class="RktValLink" data-pltdoc="x">odd?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Hence, this kind of computation is called a <span style="font-style: italic">reduction</span>.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._422))"></a>
|
|
<a name="(idx._(gentag._423))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X Y] [X Y -> Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Y</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">applies </span><span class="RktSym">f</span><span class="RktCmt"> from right to left to each item in </span><span class="RktSym">lx</span><span class="RktCmt"> and </span><span class="RktSym">b</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">b</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-n</span><span class="stt"> </span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">0</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">9</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">12</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">14</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">[X Y] [X Y -> Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Y</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">applies </span><span class="RktSym">f</span><span class="RktCmt"> from left to right to each item in </span><span class="RktSym">lx</span><span class="RktCmt"> and </span><span class="RktSym">b</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">b</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-n</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">0</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">6</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span></span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aisl-ho-list2))" x-target-lift="Figure"></a>Figure 96: </span>ISL’s abstract functions for list processing (2)</span></p></blockquote></div></p><p>The two functions in <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x">figure <span class="FigureRef">96</span></a>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>, are extremely powerful. Both <span style="font-weight: bold">reduce</span> lists to
|
|
values. The sample computations explain the abstract examples in the
|
|
headers of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> via an application of the
|
|
functions to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span>, <span class="RktVal">0</span>, and a short list. As you
|
|
can<span class="refelem"><span class="refcolumn"><span class="refcontent">Mathematics calls functions <span style="font-style: italic">associative</span> if the
|
|
order makes no difference. ISL’s <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span> is associative on integers
|
|
but not on inexacts. See below.</span></span></span> see, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> processes the list
|
|
values from right to left and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> from left to right. While for
|
|
some functions the direction makes no difference, this isn’t true in
|
|
general.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aarg-min-max))"></a><span style="font-weight: bold">Exercise</span> 256. Explain the following abstract function: <a name="(idx._(gentag._424))"></a>
|
|
</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">[X] [X -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._nelist._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of</span></a><span class="RktCmt"> X] -> X </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the (first) item in </span><span class="RktSym">lx</span><span class="RktCmt"> that </span><span style="font-weight: bold">maximizes</span><span class="RktCmt"> </span><span class="RktSym">f</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">if </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._argmax%29%29" class="RktValLink" data-pltdoc="x">argmax</a></span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x-1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> </span><span class="RktSym">==</span><span class="RktCmt"> </span><span class="RktSym">x-i</span><span class="RktCmt">, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">then </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e~3d%29%29" class="RktValLink" data-pltdoc="x">>=</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-i</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt">, </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e~3d%29%29" class="RktValLink" data-pltdoc="x">>=</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-i</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x-2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt">, ...</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._argmax%29%29" class="RktValLink" data-pltdoc="x">argmax</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Use it on concrete examples in ISL. Can you articulate an analogous
|
|
purpose statement for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._argmin%29%29" class="RktValLink" data-pltdoc="x">argmin</a></span>? <a href="part_three.html#%28counter._%28exercise._ex~3aarg-min-max%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._425))"></a>
|
|
<a name="(idx._(gentag._426))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">address</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">first-name</span><span class="hspace"> </span><span class="RktSym">last-name</span><span class="hspace"> </span><span class="RktSym">street</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._addr)"></a><span style="font-style: italic">Addr</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-address</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> associates an address with a person</span><span class="RktCmt">'</span><span class="RktCmt">s name</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._addr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Addr</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a string from first names, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">sorted in alphabetical order,</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">separated and surrounded by blank spaces</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">listing</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">string-append-with-space</span><span class="hspace"> </span><span class="RktVal">" "</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">address-first-name</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></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><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">appends two strings, prefixes with </span><span class="RktVal">" "</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string-append-with-space</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ex0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-address</span><span class="hspace"> </span><span class="RktVal">"Robert"</span><span class="hspace"> </span><span class="RktVal">"Findler"</span><span class="hspace"> </span><span class="RktVal">"South"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-address</span><span class="hspace"> </span><span class="RktVal">"Matthew"</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktVal">"Canyon"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-address</span><span class="hspace"> </span><span class="RktVal">"Shriram"</span><span class="hspace"> </span><span class="RktVal">"Krishna"</span><span class="hspace"> </span><span class="RktVal">"Yellow"</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">listing</span><span class="hspace"> </span><span class="RktSym">ex0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">" Matthew Robert Shriram "</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alist-of-names))" x-target-lift="Figure"></a>Figure 97: </span>Creating a program with abstractions</span></p></blockquote></div></p><p><div class="SIntrapara"><a href="part_three.html#%28counter._%28figure._fig~3alist-of-names%29%29" data-pltdoc="x">Figure <span class="FigureRef">97</span></a> illustrates the power of composing the
|
|
functions from <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures <span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>. Its main
|
|
function is <span class="RktSym">listing</span>. The purpose is to create a string from a
|
|
list of <span class="RktSym">address</span>es. Its purpose statement suggests three tasks and
|
|
thus the design of three functions:
|
|
</div><div class="SIntrapara"><ol><li><p>one that extracts the first names from the given list of <span class="RktSym">Addr</span>;</p></li><li><p>one that sorts these names in alphabetical order; and</p></li><li><p>one that concatenates the strings from step 2.</p></li></ol></div><div class="SIntrapara">Before you read on, you may wish to execute this plan. That is, design all
|
|
three functions and then compose them in the sense of
|
|
<a href="part_two.html#%28part._sec~3acompounding2%29" data-pltdoc="x">Composing Functions</a> to obtain your own version of <span class="RktSym">listing</span>.</div></p><p><div class="SIntrapara">In the new world of abstractions, it is possible to design a single
|
|
function that achieves the same goal. Take a close look at the innermost
|
|
expression of <span class="RktSym">listing</span> in <a href="part_three.html#%28counter._%28figure._fig~3alist-of-names%29%29" data-pltdoc="x">figure <span class="FigureRef">97</span></a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">address-first-name</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">By the purpose statement of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>, it applies
|
|
<span class="RktSym">address-first-name</span> to every single instance of <span class="RktSym">address</span>,
|
|
producing a list of first names as strings. Here is the immediately
|
|
surrounding expression:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The dots represent the result of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> expression. Since the
|
|
latter supplies a list of strings, the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> expression produces a
|
|
sorted list of first names. And that leaves us with the outermost expression:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">string-append-with-space</span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">This one reduces the sorted list of first names to a single string, using
|
|
a function named <span class="RktSym">string-append-with-space</span>. With such a suggestive
|
|
name, you can easily imagine now that this reduction concatenates all the
|
|
strings in the desired way—<wbr></wbr>even if you do not quite understand how the
|
|
combination of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> and <span class="RktSym">string-append-with-space</span> works.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3adesigning-build-list))"></a><span style="font-weight: bold">Exercise</span> 257. You can design <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> with the design recipes that you know, but they are not
|
|
going to be like the ones that ISL provides. For example, the design of
|
|
your own <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> function requires a use of the list
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> function: <a name="(idx._(gentag._427))"></a>
|
|
</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">[X Y] [X Y -> Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Y</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktSym">f*oldl</span><span class="RktCmt"> works just like </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f*oldl</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></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">a</span><span class="hspace"> </span><span class="RktVal">b</span><span class="hspace"> </span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></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">a</span><span class="hspace"> </span><span class="RktVal">b</span><span class="hspace"> </span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f*oldl</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f*oldl</span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</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></table></blockquote></div></p><p>Design <span class="RktSym">build-l*st</span>, which works just like
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span>. <span style="font-weight: bold">Hint</span> Recall the <span class="RktSym">add-at-end</span> function
|
|
from <a href="part_two.html#%28counter._%28exercise._ex~3adraw-poly0%29%29" data-pltdoc="x">exercise 193</a>. <span style="font-weight: bold">Note on Design</span> <a href="part_six.html" data-pltdoc="x">Accumulators</a> covers
|
|
the concepts needed to design these functions from scratch. <a href="part_three.html#%28counter._%28exercise._ex~3adesigning-build-list%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>16.2<tt> </tt><a name="(part._sec~3alocal-definitions)"></a>Local Definitions</h4><p>Let’s take a second look at <a href="part_three.html#%28counter._%28figure._fig~3alist-of-names%29%29" data-pltdoc="x">figure <span class="FigureRef">97</span></a>. The
|
|
<span class="RktSym">string-append-with-space</span> function clearly plays a subordinate
|
|
role and has no use outside of this narrow context. Furthermore, the
|
|
organization of the function body does not reflect the three tasks
|
|
identified above.</p><p>Almost all programming languages support some way for stating these kinds
|
|
of relationships as a part of a program. The idea is called a
|
|
<span style="font-style: italic">local definition</span>, also called a <span style="font-style: italic">private definition</span>. In
|
|
ISL, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expressions introduce locally defined functions,
|
|
variables, and structure types.</p><p><div class="SIntrapara">This section introduces the mechanics of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. In general, a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression has this shape:
|
|
<a name="(idx._(gentag._428))"></a>
|
|
<a name="(idx._(gentag._429))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">def</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">—<wbr></wbr></span><span class="RktCmt"> IN </span><span class="RktCmt">—<wbr></wbr></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">body-expression</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The evaluation of such an expression proceeds like the evaluation of a
|
|
complete program. First, the definitions are set up, which may involve the
|
|
evaluation of the right-hand side of a constant definition. Just as with
|
|
the top-level definitions that you know and love, the definitions in a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression may refer to each other. They may also refer to
|
|
parameters of the surrounding function. Second, the
|
|
<span class="RktVar">body-expression</span> is evaluated and it becomes the result of the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression. It is often helpful to separate the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> <span class="RktVar">def</span>s from the <span class="RktSym">body-expression</span> with a
|
|
comment; as indicated, we may use <span class="stt"></span><span class="stt">—<wbr></wbr></span><span class="stt"> IN </span><span class="stt">—<wbr></wbr></span><span class="stt"></span> because the word
|
|
suggests that the definitions are available in a certain expression.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._430))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._addr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Addr</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a string of first names, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">sorted in alphabetical order,</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">separated and surrounded by blank spaces</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">listing.v2</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">1. extract names </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">address-first-name</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">2. sort the names </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace"> </span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">3. append them, add spaces </span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">appends two strings, prefix with </span><span class="RktVal">" "</span><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">helper</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">concat+spaces</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">helper</span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">concat+spaces</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alisting2))" x-target-lift="Figure"></a>Figure 98: </span>Organizing a function with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span></span></p></blockquote></div></p><p><a href="part_three.html#%28counter._%28figure._fig~3alisting2%29%29" data-pltdoc="x">Figure <span class="FigureRef">98</span></a> shows a revision of
|
|
<a href="part_three.html#%28counter._%28figure._fig~3alist-of-names%29%29" data-pltdoc="x">figure <span class="FigureRef">97</span></a> using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. The body of the
|
|
<span class="RktSym">listing.v2</span> function is now a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression, which
|
|
consists of two pieces: a sequence of definitions and a body
|
|
expression. The sequence of local definitions looks exactly like a sequence
|
|
in DrRacket’s definitions area.</p><p>In this example, the sequence of definitions consists of four pieces: three
|
|
constant definitions and a single function definition. Each constant
|
|
definition represents one of the three planning tasks. The function
|
|
definition is a renamed version<span class="refelem"><span class="refcolumn"><span class="refcontent">Since the names are visible
|
|
only within the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression, shortening the name is fine.</span></span></span>
|
|
of <span class="RktSym">string-append-with-space</span>; it is used with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> to
|
|
implement the third task. The body of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> is just the name of
|
|
the third task.</p><p><div class="SIntrapara">The visually most appealing difference concerns the overall organization.
|
|
It clearly brings across that the function achieves three tasks and in
|
|
which order. As a matter of fact, this example demonstrates a general
|
|
principle of readability:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-style: italic">Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to reformulate deeply nested expressions. Use
|
|
well-chosen names to express what the expressions compute.</span></p></blockquote></div><div class="SIntrapara">Future readers appreciate it because they can comprehend the code by
|
|
looking at just the names and the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression.</div></p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Organization</span> A <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression is really just an
|
|
expression. It may show up wherever a regular expression shows up. Hence it
|
|
is possible to indicate precisely where an auxiliary function is
|
|
needed. Consider this reorganization of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression of
|
|
<span class="RktSym">listing.v2</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">concat+spaces</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">helper</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">t</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">helper</span><span class="hspace"> </span><span class="RktVal">" "</span><span class="hspace"> </span><span class="RktSym">sorted</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="RktSym">concat+spaces</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr></table></blockquote></div><div class="SIntrapara">It consists of exactly three definitions, suggesting it takes three
|
|
computation steps. The third definition consists of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
expression on the right-hand side, which expresses that <span class="RktSym">helper</span> is
|
|
really just needed for the third step.</div></p><p>Whether you want to express relationships among the pieces of a program
|
|
with such precision depends on two constraints: the programming language
|
|
and how long the code is expected to live. Some languages cannot even express
|
|
the idea that <span class="RktSym">helper</span> is useful for the third step only. Then
|
|
again, you need to balance the time it takes to create the program and the
|
|
expectation that you or someone needs to revisit it and comprehend the code
|
|
again. The preference of the Racket team is to err on the side of future
|
|
developers because the team members know that no program is ever finished
|
|
and all programs will need fixing. <span style="font-weight: bold">End</span></p><p><div class="SIntrapara"><a name="(idx._(gentag._431))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] [</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">-> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a version of </span><span class="RktSym">alon0</span><span class="RktCmt">, sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktSym">alon0</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces the sorted version of </span><span class="RktSym">alon</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">isort</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">isort</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</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="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">inserts </span><span class="RktSym">n</span><span class="RktCmt"> into the sorted list of numbers </span><span class="RktSym">alon</span><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">n</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="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</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><span class="RktPn">(</span><span class="RktSym">isort</span><span class="hspace"> </span><span class="RktSym">alon0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asort-local))" x-target-lift="Figure"></a>Figure 99: </span>Organizing interconnected function definitions with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span></span></p></blockquote></div></p><p><a href="part_three.html#%28counter._%28figure._fig~3asort-local%29%29" data-pltdoc="x">Figure <span class="FigureRef">99</span></a> presents a second example.
|
|
The organization of this function definition informs the reader that
|
|
<span class="RktSym">sort-cmp</span> calls on two auxiliary functions: <span class="RktSym">isort</span> and
|
|
<span class="RktSym">insert</span>. By locality, it becomes obvious that the adjective
|
|
“sorted” in the purpose statement of <span class="RktSym">insert</span> refers to
|
|
<span class="RktSym">isort</span>. In other words, <span class="RktSym">insert</span> is useful in this context
|
|
only; a programmer should not try to use it elsewhere, out of context.
|
|
While this constraint is already important in the original definition of
|
|
the <span class="RktSym">sort-cmp</span> function, a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression expresses it as
|
|
part of the program.</p><p>Another important aspect of this reorganization of <span class="RktSym">sort-cmp</span>’s
|
|
definition concerns the visibility of <span class="RktSym">cmp</span>, the second function
|
|
parameter. The locally defined functions can refer to <span class="RktSym">cmp</span> because
|
|
it is defined in the context of the definitions. By <span style="font-weight: bold">not</span> passing
|
|
around <span class="RktSym">cmp</span> from <span class="RktSym">isort</span> to <span class="RktSym">insert</span> (or back), the
|
|
reader can immediately infer that <span class="RktSym">cmp</span> remains the same throughout
|
|
the sorting process.</p><p><a name="(counter._(exercise._ex~3adraw-poly-local))"></a><span style="font-weight: bold">Exercise</span> 258. Use a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression to organize
|
|
the functions for drawing a polygon in <a href="part_two.html#%28counter._%28figure._fig~3adraw-poly%29%29" data-pltdoc="x">figure <span class="FigureRef">73</span></a>. If a
|
|
globally defined function is widely useful, do not make it local. <a href="part_three.html#%28counter._%28exercise._ex~3adraw-poly-local%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3apermute-local))"></a><span style="font-weight: bold">Exercise</span> 259. Use a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression to organize
|
|
the functions for rearranging words from <a href="part_two.html#%28part._sec~3apermute%29" data-pltdoc="x">Word Games, the Heart of the Problem</a>. <a href="part_three.html#%28counter._%28exercise._ex~3apermute-local%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._432))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._nelon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Nelon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines the smallest number on </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf.v2</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktSym">smallest-in-rest</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">inf.v2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">smallest-in-rest</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></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alocal-performance))" x-target-lift="Figure"></a>Figure 100: </span>Using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> may improve performance</span></p></blockquote></div></p><p><div class="SIntrapara">Our final example of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>’s usefulness concerns performance.
|
|
Consider the definition of <span class="RktSym">inf</span> in
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aex-abs-min-max%29%29" data-pltdoc="x">figure <span class="FigureRef">89</span></a>. It contains two copies of
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">which is the natural recursion in the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line. Depending on the
|
|
outcome of the question, the expression is evaluated twice. Using
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to name this expression yields an improvement to
|
|
the function’s readability as well as to its performance.</div></p><p><a href="part_three.html#%28counter._%28figure._fig~3alocal-performance%29%29" data-pltdoc="x">Figure <span class="FigureRef">100</span></a> displays the revised version. Here the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression shows up in the middle of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
|
|
expression. It defines a constant whose value is the result of a natural
|
|
recursion. Now recall that the evaluation of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression
|
|
evaluates the definitions once before proceeding to the body, meaning
|
|
<span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> is evaluated once while the body of the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression refers to the result twice. Thus, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
saves the re-evaluation of <span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> at each stage in the
|
|
computation.</p><p><a name="(counter._(exercise._ex~3aabs-min-max-local))"></a><span style="font-weight: bold">Exercise</span> 260. Confirm the insight about the performance
|
|
of <span class="RktSym">inf.v2</span> by repeating the performance experiment of
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3aabs-min-max%29%29" data-pltdoc="x">exercise 238</a>. <a href="part_three.html#%28counter._%28exercise._ex~3aabs-min-max-local%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._433))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates an </span><a href="part_three.html#%28tech._inventory%29" class="techoutside" data-pltdoc="x"><span class="techinside">Inventory</span></a><span class="RktCmt"> from </span><span class="RktSym">an-inv</span><span class="RktCmt"> for all</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">those items that cost less than a dollar</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract1</span><span class="hspace"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">an-inv</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1.0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">extract1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span><span class="RktPn">)</span></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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">extract1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span><span class="RktPn">)</span></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></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3alocal-interm1))" x-target-lift="Figure"></a>Figure 101: </span>A function on inventories, see <a href="part_three.html#%28counter._%28exercise._ex~3alocal-interm1%29%29" data-pltdoc="x">exercise 261</a></span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3alocal-interm1))"></a><span style="font-weight: bold">Exercise</span> 261. Consider the function definition in
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aex~3alocal-interm1%29%29" data-pltdoc="x">figure <span class="FigureRef">101</span></a>. Both clauses in the nested
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression extract the first item from <span class="RktSym">an-inv</span> and
|
|
both compute <span class="RktPn">(</span><span class="RktSym">extract1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">an-inv</span><span class="RktPn">)</span><span class="RktPn">)</span>. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to name
|
|
this expression. Does this help increase the speed at which the function
|
|
computes its result? Significantly? A little bit? Not at all? <a href="part_three.html#%28counter._%28exercise._ex~3alocal-interm1%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>16.3<tt> </tt><a name="(part._sec~3alocal-is-power)"></a>Local Definitions Add Expressive Power</h4><p>The third and last example illustrates how <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> adds expressive
|
|
power to BSL and BSL+. <a href="part_two.html#%28part._sec~3asec-fsm-list%29" data-pltdoc="x">Finite State Machines</a> presents the design
|
|
of a world program that simulates how a finite state machine recognizes
|
|
sequences of keystrokes. While the data analysis leads in a natural
|
|
manner to the data definitions in <a href="part_two.html#%28counter._%28figure._fig~3afsm1%29%29" data-pltdoc="x">figure <span class="FigureRef">82</span></a>, an attempt to
|
|
design the main function of the world program fails. Specifically, even
|
|
though the given finite state machine remains the same over the course of
|
|
the simulation, the state of the world must include it so that the program
|
|
can transition from one state to the next when the player presses a key.</p><p><div class="SIntrapara"><a name="(idx._(gentag._434))"></a>
|
|
<a name="(idx._(gentag._435))"></a>
|
|
<a name="(idx._(gentag._436))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">matches the keys pressed by a player with the given </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">simulate</span><span class="hspace"> </span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">State of the World: </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">key-event</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktSym">s</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://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">s0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state</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><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders current state as colored square </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">state-as-colored-square</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://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._square%29%29" class="RktValLink" data-pltdoc="x">square</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">"solid"</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></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the </span><span class="RktSym">current</span><span class="RktCmt"> state</span><span class="RktCmt">'</span><span class="RktCmt">s successor in </span><span class="RktSym">fsm</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">transitions</span><span class="hspace"> </span><span class="RktSym">current</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">transitions</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">"not found"</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">transitions</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">state=?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">transition-current</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">current</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">transition-next</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">find</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">transitions</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">current</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></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alocal-is-power))" x-target-lift="Figure"></a>Figure 102: </span>Power from local function definitions</span></p></blockquote></div></p><p><a href="part_three.html#%28counter._%28figure._fig~3alocal-is-power%29%29" data-pltdoc="x">Figure <span class="FigureRef">102</span></a> shows an ISL solution to the problem. It
|
|
uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> function definitions and can thus equate the state of
|
|
the world with the current state of the finite state
|
|
machine. Specifically, <span class="RktSym">simulate</span> locally defines the key-event
|
|
handler, which consumes only the current state of the world and the
|
|
<a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a> that represents the player’s keystroke. Because this
|
|
locally defined function can refer to the given finite state machine
|
|
<span class="RktSym">fsm</span>, it is possible to find the next state in the transition
|
|
table—<wbr></wbr>even though the transition table is <span style="font-weight: bold">not</span> an argument to this
|
|
function.</p><p>As the figure also shows, all other functions are defined in parallel to
|
|
the main function. This includes the function <span class="RktSym">find</span>, which
|
|
performs the actual search in the transition table. The key improvement
|
|
over BSL is that a locally defined function can reference <span style="font-weight: bold">both</span>
|
|
parameters to the function <span style="font-weight: bold">and</span> globally defined auxiliary
|
|
functions.</p><p>In short, this program organization signals to a future reader exactly the
|
|
insights that the data analysis stage of the design recipe for world
|
|
programs finds. First, the given representation of the finite state
|
|
machine remains unchanged. Second, what changes over the course of the
|
|
simulation is the current state of the finite machine.</p><p>The lesson is that the chosen programming language affects a programmer’s
|
|
ability to express solutions, as well as a future reader’s ability to recognize
|
|
the design insight of the original creator.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alocal-for-diagonal))"></a><span style="font-weight: bold">Exercise</span> 262. Design the function <span class="RktSym">identityM</span>,
|
|
which creates diagonal squares of <span class="RktVal">0</span>s and
|
|
<span class="RktVal">1</span>s:<span class="refelem"><span class="refcolumn"><span class="refcontent">Linear algebra calls these squares
|
|
<span style="font-style: italic">identity</span> matrices.</span></span></span>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">identityM</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list (list 1))</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">identityM</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list (list 1 0 0) (list 0 1 0) (list 0 0 1))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Use the <a name="(idx._(gentag._437))"></a>structural design recipe and exploit the power of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3alocal-for-diagonal%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>16.4<tt> </tt><a name="(part._sec~3aeval-local)"></a>Computing with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span></h4><p><div class="SIntrapara">ISL’s <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression calls for the first rule of calculation
|
|
that is truly beyond pre-algebra knowledge. The rule is relatively simple
|
|
but quite unusual. It’s best illustrated with some examples. We start with
|
|
a second look at this definition:<a name="(idx._(gentag._438))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">simulate</span><span class="hspace"> </span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">key-event</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktSym">s</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://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">s0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state</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">Now suppose we wish to calculate what DrRacket might produce for
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">simulate</span><span class="hspace"> </span><span class="RktSym">AN-FSM</span><span class="hspace"> </span><span class="RktSym">A-STATE</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">where <span class="RktSym">AN-FSM</span> and <span class="RktSym">A-STATE</span> are unknown values.
|
|
Using the usual substitution rule, we proceed as follows:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">key-event</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">AN-FSM</span><span class="hspace"> </span><span class="RktSym">s</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://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">A-STATE</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This is the body of <span class="RktSym">simulate</span> with all occurrences of <span class="RktSym">fsm</span>
|
|
and <span class="RktSym">s0</span> replaced by the argument values
|
|
<span class="RktSym">AN-FSM</span> and <span class="RktSym">A-STATE</span>, respectively.</div></p><p><div class="SIntrapara">At this point we are stuck because the expression is a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
expression, and we don’t know how to calculate with it. So here we go. To
|
|
deal with a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression in a program evaluation, we proceed
|
|
in two steps:
|
|
</div><div class="SIntrapara"><ol><li><p>We rename the locally defined constants and functions to use names
|
|
that aren’t used elsewhere in the program.</p></li><li><p>We lift the definitions in the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression to the
|
|
top level and evaluate the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression next.</p></li></ol></div><div class="SIntrapara">Stop! Don’t think. Accept the two steps for now.</div></p><p><div class="SIntrapara">Let’s apply these two steps to our running example, one at a time:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">find-next-state-1</span></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">key-event</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">AN-FSM</span><span class="hspace"> </span><span class="RktSym">a-state</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://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">A-STATE</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">find-next-state-1</span></span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Our choice is to append “-1” to the end of the function name. If this
|
|
variant of the name already exists, we use “-2” instead, and so on.
|
|
So here is the result of step 2:
|
|
<span class="refelem"><span class="refcolumn"><span class="refcontent">We use <img src="pict_115.png" alt="image" width="9" height="8"/> to indicate that the step produces two pieces.</span></span></span>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state-1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">key-event</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">AN-FSM</span><span class="hspace"> </span><span class="RktSym">a-state</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_116.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">A-STATE</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state-1</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The
|
|
result is an ordinary program: some globally defined constants and
|
|
functions followed by an expression. The normal rules apply, and there is
|
|
nothing else to say.</div></p><p><div class="SIntrapara">At this point, it is time to rationalize the two steps. For the renaming
|
|
step, we use a variant of the <span class="RktSym">inf</span> function from <a href="part_three.html#%28counter._%28figure._fig~3alocal-performance%29%29" data-pltdoc="x">figure <span class="FigureRef">100</span></a>.
|
|
Clearly,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">1</span></p></blockquote></div><div class="SIntrapara">The question is whether you can show the calculations that DrRacket performs
|
|
to determine this result.</div></p><p><div class="SIntrapara">The first step is straightforward:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</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">We substitute <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span> for <span class="RktSym">l</span>.</div></p><p><div class="SIntrapara">Since the list isn’t empty, we skip the steps for evaluating the
|
|
conditional and focus on the next expression to be evaluated:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Applying the two steps for the rule of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> yields two parts: the
|
|
local definition lifted to the top and the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
expression. Here is how we write this down:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_117.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Curiously, the next expression we need to evaluate is the
|
|
right-hand side of a constant definition in a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
expression. But the point of computing is that you can replace
|
|
expressions with their equivalents wherever you want:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</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><img src="pict_118.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Once again, we skip the conditional steps and focus on the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span>
|
|
clause, which is also a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression. Indeed it is another
|
|
variant of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression in the definition of <span class="RktSym">inf</span>,
|
|
with a different list value substituted for the parameter:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_119.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-3</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Because it originates from the same <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression in
|
|
<span class="RktSym">inf</span>, it uses the same name for the constant,
|
|
<span class="RktSym">smallest-in-rest</span>. <span style="font-weight: bold">If we didn’t rename local definitions
|
|
before lifting them, we would introduce two conflicting definitions for the
|
|
same name</span>, and conflicting definitions are catastrophic for mathematical
|
|
calculations.</div></p><p><div class="SIntrapara">Here is how we continue:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_120.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-2</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_121.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">smallest-in-rest-1</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The key is that we now have <span style="font-weight: bold">two</span> definitions generated from <span style="font-weight: bold">one
|
|
and the same</span> <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression in the function definition. As a
|
|
matter of fact we get one such definition per item in the given list (minus
|
|
1).</div></p><p><a name="(counter._(exercise._ex~3acalc-local1))"></a><span style="font-weight: bold">Exercise</span> 263. Use DrRacket’s stepper to study the steps of this
|
|
calculation in detail. <a href="part_three.html#%28counter._%28exercise._ex~3acalc-local1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3acalc-local2))"></a><span style="font-weight: bold">Exercise</span> 264. Use DrRacket’s stepper to calculate out how it
|
|
evaluates
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">sup</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">where <span class="RktSym">sup</span> is the function from <a href="part_three.html#%28counter._%28figure._fig~3aex-abs-min-max%29%29" data-pltdoc="x">figure <span class="FigureRef">89</span></a>
|
|
equipped with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3acalc-local2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>This passage and some of the following exercises already need the “Intermediate
|
|
Student with <span class="stt">lambda</span>” language. In DrRacket, choose the corresponding
|
|
entry from the “How to Design Programs” submenu in the
|
|
“Language” menu.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">For the explanation of the lifting step, we use a toy example that gets
|
|
to the heart of the issue, namely, that functions are now values:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Deep down we know that this is equivalent to <span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> where
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">but the rules of pre-algebra don’t apply. The key is that <span style="font-weight: bold">functions
|
|
can be the result of expressions, including <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expressions</span>.
|
|
And the best way to think of this is to move such <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
definitions to the top and to deal with them like ordinary
|
|
definitions. Doing so renders the definition visible for every step of the
|
|
calculation. By now you also understand that the renaming step makes sure that
|
|
the lifting of definitions does not accidentally conflate names or
|
|
introduce conflicting definitions.</div></p><p><div class="SIntrapara">Here are the first two steps of the calculation:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f-1</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktSym">f-1</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f-1</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><img src="pict_122.png" alt="image" width="9" height="8"/></td></tr><tr><td><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">f-1</span></span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Remember that the second step of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> rule replaces the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression with its body. In this case, the body is just
|
|
the name of the function, and its surrounding is an application to
|
|
<span class="RktVal">1</span>. The rest is arithmetic:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">f-1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sqr%29%29" class="RktValLink" data-pltdoc="x">sqr</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">7</span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3acalc-local-3))"></a><span style="font-weight: bold">Exercise</span> 265. Use DrRacket’s stepper to fill in any gaps above. <a href="part_three.html#%28counter._%28exercise._ex~3acalc-local-3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3acalc-local-4))"></a><span style="font-weight: bold">Exercise</span> 266. Use DrRacket’s stepper to find out how ISL
|
|
evaluates
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">3</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">4</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._odd~3f%29%29" class="RktValLink" data-pltdoc="x">odd?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">g</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="RktSym">f</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">g</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">to <span class="RktVal">5</span>. <a href="part_three.html#%28counter._%28exercise._ex~3acalc-local-4%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>16.5<tt> </tt><a name="(part._sec~3ausage-examples)"></a>Using Abstractions, by Example</h4><p><div class="SIntrapara">Now that you understand <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>, you can easily use the abstractions
|
|
from <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures <span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>. Let’s look at
|
|
examples, starting with this one:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design <span class="RktSym">add-3-to-all</span>. The function
|
|
consumes a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and adds <span class="RktVal">3</span> to the x-coordinates
|
|
of each.</p></blockquote></div><div class="SIntrapara">If we follow the design recipe and take the problem statement as a purpose
|
|
statement, we can quickly step through the first three steps: <a name="(idx._(gentag._439))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds </span><span class="RktVal">3</span><span class="RktCmt"> to each x-coordinate on the given list </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">0</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span><span class="hspace"> </span><span class="RktSym">lop</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></td></tr></table></blockquote></div><div class="SIntrapara">While you can run the program, doing so signals a failure in the one test
|
|
case because the function returns the default value <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</div></p><p>At this point, we stop and ask what kind of function we are dealing
|
|
with. Clearly, <span class="RktSym">add-3-to-all</span> is a list-processing
|
|
function. The question is whether it is like any of the functions in
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures <span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>. The signature tells us that
|
|
<span class="RktSym">add-3-to-all</span> is a list-processing function that consumes and
|
|
produces a list. In the two figures, we have several
|
|
functions with similar signatures: <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span>, and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span>.</p><p>The purpose statement and example also tell you that <span class="RktSym">add-3-to-all</span>
|
|
deals with each <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> separately and assembles the results into a
|
|
single list. Some reflection also confirms that the resulting
|
|
list contains as many items as the given list. All this thinking points
|
|
to one function—<wbr></wbr><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>—<wbr></wbr>because the point of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> is
|
|
to drop items from the list and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> has an extremely specific
|
|
purpose.</p><p><div class="SIntrapara">Here is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>’s signature again:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X Y] [X -> Y] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> Y]</span></p></blockquote></div><div class="SIntrapara">It tells us that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> consumes a function from <span class="RktCmt">X</span> to <span class="RktCmt">Y</span> and a list
|
|
of <span class="RktCmt">X</span>s. Given that <span class="RktSym">add-3-to-all</span> consumes a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s,
|
|
we know that <span class="RktCmt">X</span> stands for <span class="RktSym">Posn</span>. Similarly, <span class="RktSym">add-3-to-all</span>
|
|
is to produce a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, and this means we replace <span class="RktCmt">Y</span> with
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p><p><div class="SIntrapara">From the analysis of the signature, we conclude that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> can do
|
|
the job of <span class="RktSym">add-3-to-all</span> when given the right function
|
|
from <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s to <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>, we can express
|
|
this idea as a template for <span class="RktSym">add-3-to-all</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">...</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fp</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">fp</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Doing so reduces the problem to defining a function on <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s.</div></p><p><div class="SIntrapara">Given the example for <span class="RktSym">add-3-to-all</span> and the abstract example for
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>, you can actually imagine how the evaluation proceeds:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">fp</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fp</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fp</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">And that shows how <span class="RktSym">fp</span> is applied to every single <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>
|
|
on the given list, meaning it is its job to add <span class="RktVal">3</span> to the x-coordinate.</div></p><p><div class="SIntrapara">From here, it is straightforward to wrap up the definition:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds </span><span class="RktVal">3</span><span class="RktCmt"> to the x-coordinate of </span><span class="RktSym">p</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-x</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktSym">add-3-to-x</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We chose <span class="RktSym">add-3-to-x</span> as the name for the local function because
|
|
the name tells you what it computes. It adds <span class="RktVal">3</span> to the
|
|
x-coordinate of one <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p><p><div class="SIntrapara">You may now think that using abstractions is hard. Keep in mind, though,
|
|
that this first example spells out every single detail and that it does so
|
|
because we wish to teach you how to pick the proper abstraction. Let’s
|
|
take a look at a second example a bit more quickly:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a function that eliminates all <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s with
|
|
y-coordinates larger than <span class="RktVal">100</span> from some given list.</p></blockquote></div><div class="SIntrapara">The first three steps of the design recipe yield this: <a name="(idx._(gentag._440))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">eliminates </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">s whose y-coordinate is </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="RktCmt"> </span><span class="RktVal">100</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keep-good</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">110</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">60</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">60</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keep-good</span><span class="hspace"> </span><span class="RktSym">lop</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></td></tr></table></blockquote></div><div class="SIntrapara">By now you may have guessed that this function is like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span>,
|
|
whose purpose is to separate the “good” from the “bad.”</div></p><p><div class="SIntrapara">With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> thrown in, the next step is also straightforward:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keep-good</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">should this </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> stay on the list</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">good?</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktSym">good?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> function definition introduces the helper function
|
|
needed for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span>, and the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression
|
|
applies <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> to this local function and the given list. The
|
|
local function is called <span class="RktSym">good?</span> because <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> retains
|
|
all those items of <span class="RktSym">lop</span> for which <span class="RktSym">good?</span> produces
|
|
<span class="RktVal">#true</span>.</div></p><p>Before you read on, analyze the signature of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> and
|
|
<span class="RktSym">keep-good</span> and determine why the helper function consumes
|
|
individual <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and produces <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s.</p><p><div class="SIntrapara">Putting all of our ideas together yields this definition:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keep-good</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">should this </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> stay on the list</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">good?</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._not%29%29" class="RktValLink" data-pltdoc="x">not</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">100</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktSym">good?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Explain the definition of <span class="RktSym">good?</span> and simplify it.</div></p><p><div class="SIntrapara">Before we spell out a design recipe, let’s deal with one more example:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a function that determines whether any of a list of
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s is close to some given position <span class="RktSym">pt</span> where “close” means
|
|
a distance of at most <span class="RktVal">5</span> pixels.</p></blockquote></div><div class="SIntrapara">This problem clearly consists of two distinct parts: one concerns
|
|
processing the list and the other one calls for a function that determines
|
|
whether the distance between a point and <span class="RktSym">pt</span> is “close.” Since this
|
|
second part is unrelated to the reuse of abstractions for list traversals,
|
|
we assume the existence of an appropriate function:<a name="(idx._(gentag._441))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is the distance between </span><span class="RktSym">p</span><span class="RktCmt"> and </span><span class="RktSym">q</span><span class="RktCmt"> less than </span><span class="RktSym">d</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close-to</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">q</span><span class="hspace"> </span><span class="RktSym">d</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You should complete this definition on your own.</div></p><p><div class="SIntrapara">As required by the problem statement, the function consumes two
|
|
arguments: the list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and the “given” point
|
|
<span class="RktSym">pt</span>. It produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>: <a name="(idx._(gentag._442))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is any </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> on </span><span class="RktSym">lop</span><span class="RktCmt"> close to </span><span class="RktSym">pt</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">47</span><span class="hspace"> </span><span class="RktVal">54</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">60</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">50</span><span class="hspace"> </span><span class="RktVal">50</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The signature differentiates this example from the preceding ones.</div></p><p>The <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> range also gives away a clue with respect to
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures <span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>. Only two functions in this list produce
|
|
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> values—<wbr></wbr><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span>—<wbr></wbr>and they must
|
|
be primary candidates for defining <span class="RktSym">close?</span>’s body. While the
|
|
explanation of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> says that some property must hold for every
|
|
item on the given list, the purpose statement for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> tells us
|
|
that it looks for only <span style="font-weight: bold">one</span> such item. Given that <span class="RktSym">close?</span>
|
|
just checks whether one of the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s is close to <span class="RktSym">pt</span>, we
|
|
should try <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> first.</p><p><div class="SIntrapara">Let’s apply our standard “trick” of adding a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> whose body
|
|
uses the chosen abstraction on some locally defined function and the given
|
|
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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">...</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">is-one-close?</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace"> </span><span class="RktSym">close-to?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Following the description of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span>, the local function consumes
|
|
one item of the list at a time. This accounts for the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> part of its
|
|
signature. Also, the local function is expected to produce <span class="RktVal">#true</span>
|
|
or <span class="RktVal">#false</span>, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> checks these results until it finds
|
|
<span class="RktVal">#true</span>.</div></p><p><div class="SIntrapara">Here is a comparison of the signature of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> and
|
|
<span class="RktSym">close?</span>, starting with the former:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X] [X -> Boolean] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></blockquote></div><div class="SIntrapara">In our case, the list argument is a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. Hence X
|
|
stands for <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>, which explains what <span class="RktSym">is-one-close?</span>
|
|
consumes. Furthermore, it determines that the result of the local function
|
|
must be <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> so that it can work as the first argument to
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span>.</div></p><p><div class="SIntrapara">The rest of the work requires just a bit more thinking. While
|
|
<span class="RktSym">is-one-close?</span> consumes one argument—<wbr></wbr>a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>—<wbr></wbr>the
|
|
<span class="RktSym">close-to</span> function consumes three: two <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and
|
|
a “tolerance” value. While the argument of <span class="RktSym">is-one-close?</span> is one
|
|
of the two <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, it is also obvious that the other one is
|
|
<span class="RktSym">pt</span>, the argument of <span class="RktSym">close?</span> itself. Naturally the
|
|
“tolerance” argument is <span class="RktVal">5</span>, as stated in the problem:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is one shot close to </span><span class="RktSym">pt</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">is-one-close?</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close-to</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="hspace"> </span><span class="RktSym">CLOSENESS</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace"> </span><span class="RktSym">is-one-close?</span><span class="hspace"> </span><span class="RktSym">lop</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">CLOSENESS</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">in terms of pixels </span></td></tr></table></blockquote></div><div class="SIntrapara">Note two properties of this definition. First, we stick to the rule that
|
|
constants deserve definitions. Second, the reference to <span class="RktSym">pt</span> in
|
|
<span class="RktSym">is-one-close?</span> signals that this <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> stays the same for the
|
|
entire traversal of <span class="RktSym">lop</span>.</div></p><h4>16.6<tt> </tt><a name="(part._sec~3adesigning-with-abstraction)"></a>Designing with Abstractions</h4><p><div class="SIntrapara">The three sample problems from the preceding section suffice for
|
|
formulating a <a name="(idx._(gentag._443))"></a>design recipe:
|
|
</div><div class="SIntrapara"><ol><li><p>Step 1 is <span style="font-weight: bold">to follow the design recipe for functions</span> for three
|
|
steps. Specifically, you should distill the problem statement into a
|
|
signature, a purpose statement, an example, and a stub definition.</p><p><div class="SIntrapara">Consider the problem of defining a function that places small red circles
|
|
on a <img src="pict_123.png" alt="image" width="52" height="9"/> canvas for a given list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. The first three
|
|
steps of the design recipe yields this much: <a name="(idx._(gentag._444))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds the </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">s on </span><span class="RktSym">lop</span><span class="RktCmt"> to the empty scene </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">31</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://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">DOT</span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">31</span><span class="hspace"> </span><span class="RktSym">MT-SCENE</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">MT-SCENE</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Add definitions for the constants so DrRacket can run the code.</div></p></li><li><p>Next we exploit the signature and purpose statement to find a
|
|
matching abstraction. <span style="font-weight: bold">To match</span> means to pick an abstraction whose
|
|
purpose is more general than the one for the function to be designed; it
|
|
also means that the signatures are related. It is often best to start with
|
|
the desired output and to find an abstraction that has the same or a more
|
|
general output.</p><p><div class="SIntrapara">For our running example, the desired output is an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>. While none
|
|
of the available abstractions produces an image, two of them have a
|
|
variable to the right of
|
|
</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">foldr : [X Y] [X Y -> Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Y</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">foldl : [X Y] [X Y -> Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Y</span></td></tr></table></blockquote></div><div class="SIntrapara">meaning we can plug in any data collection we want. If we do use
|
|
<a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>, the signature on the left of <span class="RktCmt">-></span>
|
|
demands a helper function that consumes an <span class="RktCmt">X</span>
|
|
together with an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a> and produces an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>. Furthermore, since the given list contains
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, <span class="RktCmt">X</span> does stand for the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> collection.</div></p></li><li><p>Write down <span style="font-weight: bold">a template</span>. For the reuse of abstractions, a
|
|
template uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> for two different purposes. The first one is
|
|
to note which abstraction to use, and how, in the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
|
|
expression. The second one is to write down a stub for the helper function:
|
|
its signature, its purpose (optionally), and its header. Keep in mind that
|
|
the signature comparison in the preceding step suggests most of the
|
|
signature for the auxiliary function.</p><p><div class="SIntrapara">Here is what this template looks like for our running example if we choose
|
|
the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> function:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">MT-SCENE</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> description calls for a “base” <span class="RktSym">Image</span> value,
|
|
to be used if or when the list is empty. In our case, we clearly want the
|
|
empty canvas for this case. Otherwise, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> uses a helper
|
|
function and traverses the list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s.</div></p></li><li><p>Finally, it is time to define the auxiliary function inside
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. In most cases, this function consumes relatively
|
|
simple kinds of data, like those encountered in <a href="part_one.html" data-pltdoc="x">Fixed-Size Data</a>. You
|
|
know how to design those in principle. The difference is that now you
|
|
use not only the function’s arguments and global constants but also the
|
|
arguments of the surrounding function.</p><p><div class="SIntrapara">In our running example, the purpose of the helper function is to add one
|
|
dot to the given scene, which you can (1) guess or (2) derive from the
|
|
example:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds a </span><span class="RktSym">DOT</span><span class="RktCmt"> at </span><span class="RktSym">p</span><span class="RktCmt"> to </span><span class="RktSym">scene</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">DOT</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">scene</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">MT-SCENE</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p></li><li><p>The last step is <span style="font-weight: bold">to test</span> the definition in the usual manner.</p><p>For abstract functions, it is occasionally possible to use the abstract
|
|
example of their purpose statement to confirm their workings at a more
|
|
general level. You may wish to use the abstract example for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span>
|
|
to confirm that <span class="RktSym">dots</span> does add one dot after another to the
|
|
background scene.</p></li></ol></div><div class="SIntrapara">In the third step, we picked <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> without further ado.
|
|
Experiment with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> to see how it would help complete this
|
|
function. Functions like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> are well-known
|
|
and are spreading in usage in various forms. Becoming familiar with them
|
|
is a good idea, and that’s the point of the next two sections.</div></p><h4>16.7<tt> </tt><a name="(part._sec~3aabstraction-exercises)"></a>Finger Exercises: Abstraction</h4><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Some of these exercises already need the “Intermediate
|
|
Student with <span class="stt">lambda</span>” language. In DrRacket, choose the corresponding
|
|
entry from the “How to Design Programs” submenu in the
|
|
“Language” menu.</p></blockquote></blockquote></blockquote><p><a name="(counter._(exercise._ex~3ause-map))"></a><span style="font-weight: bold">Exercise</span> 267. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> to define the function
|
|
<span class="RktSym">convert-euro</span>, which converts a list of US$ amounts into a
|
|
list of € amounts based on an exchange rate of US$<span style="font-style: italic"></span>1<span style="font-style: italic">.</span>0<span style="font-style: italic"></span>6<span style="font-style: italic"></span> per
|
|
€ (on April 13, 2017).</p><p>Also use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> to define <span class="RktSym">convertFC</span>, which converts a list
|
|
of Fahrenheit measurements to a list of Celsius measurements.</p><p>Finally, try your hand at <span class="RktSym">translate</span>, a function that translates a
|
|
list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s into a list of lists of pairs of numbers. <a href="part_three.html#%28counter._%28exercise._ex~3ause-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3asort-abstract))"></a><span style="font-weight: bold">Exercise</span> 268. An inventory record specifies the name of an
|
|
item, a description, the acquisition price, and the recommended sales
|
|
price.</p><p>Define a function that sorts a list of inventory records by the difference
|
|
between the two prices. <a href="part_three.html#%28counter._%28exercise._ex~3asort-abstract%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3ause-filter))"></a><span style="font-weight: bold">Exercise</span> 269. Define <span class="RktSym">eliminate-expensive</span>. The function consumes a
|
|
number, <span class="RktSym">ua</span>, and a list of inventory records, and it produces a list of
|
|
all those structures whose sales price is below <span class="RktSym">ua</span>.</p><p>Then use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> to define <span class="RktSym">recall</span>, which consumes the name
|
|
of an inventory item, called <span class="RktSym">ty</span>, and a list of inventory records and which
|
|
produces a list of inventory records that do not use the name <span class="RktSym">ty</span>.</p><p>In addition, define <span class="RktSym">selection</span>, which consumes two lists of names
|
|
and selects all those from the second one that are also on the first. <a href="part_three.html#%28counter._%28exercise._ex~3ause-filter%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3abuild-list1))"></a><span style="font-weight: bold">Exercise</span> 270. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span> to define a function that
|
|
</div><div class="SIntrapara"><ol><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">0</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">n</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span> for any natural number
|
|
<span class="RktSym">n</span>;</p></li><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">1</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktMeta"></span> for any natural number <span class="RktSym">n</span>;</p></li><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1/2</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span style="font-style: italic"></span>1<span style="font-style: italic">/n</span><span class="RktPn">)</span> for any natural number <span class="RktSym">n</span>;</p></li><li><p>creates the list of the first <span class="RktSym">n</span> even numbers; and</p></li><li><p>creates a diagonal square of <span class="RktVal">0</span>s and <span class="RktVal">1</span>s; see <a href="part_three.html#%28counter._%28exercise._ex~3alocal-for-diagonal%29%29" data-pltdoc="x">exercise 262</a>.</p></li></ol></div><div class="SIntrapara">Finally, define <span class="RktSym">tabulate</span> from <a href="part_three.html#%28counter._%28exercise._ex~3aabs-tabulate%29%29" data-pltdoc="x">exercise 250</a> using
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3abuild-list1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3aand-or-map))"></a><span style="font-weight: bold">Exercise</span> 271. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> to define
|
|
<span class="RktSym">find-name</span>. The function consumes a name and a list of names. It
|
|
determines whether any of the names on the latter are equal to or an
|
|
extension of the former.</p><p>With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> you can define a function that checks all names on a
|
|
list of names that start with the letter <span class="RktVal">"a"</span>.</p><p>Should you use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> to define a function that
|
|
ensures that no name on some list exceeds a given width?
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3aand-or-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afold-append))"></a><span style="font-weight: bold">Exercise</span> 272. Recall that the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span> function in
|
|
ISL concatenates the items of two lists or, equivalently, replaces
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> at the end of the first list with the second 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> to define <span class="RktSym">append-from-fold</span>. What happens if you
|
|
replace <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>?</div></p><p>Now use one of the fold functions to define functions that compute the sum
|
|
and the product, respectively, of a list of numbers.</p><p>With one of the fold functions, you can define a function that horizontally
|
|
composes a list of <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>s. <span style="font-weight: bold">Hints</span> (1) Look up <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span>. Can you use the other fold function? Also define a
|
|
function that stacks a list of images vertically. (2) Check for
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._above%29%29" class="RktValLink" data-pltdoc="x">above</a></span> in the teac=hoacks. <a href="part_three.html#%28counter._%28exercise._ex~3afold-append%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afold-map))"></a><span style="font-weight: bold">Exercise</span> 273. The fold functions are so powerful that you can
|
|
define almost any list processing functions with them. Use <span class="RktSym">fold</span> to
|
|
define <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3afold-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aprefix-isl))"></a><span style="font-weight: bold">Exercise</span> 274. Use existing abstractions to define the
|
|
<span class="RktSym">prefixes</span> and <span class="RktSym">suffixes</span> functions from
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3aprefix-bsl%29%29" data-pltdoc="x">exercise 190</a>. Ensure that they pass the same tests as the original
|
|
function. <a href="part_three.html#%28counter._%28exercise._ex~3aprefix-isl%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>16.8<tt> </tt><a name="(part._sec~3aproj-abstraction)"></a>Projects: Abstraction</h4><p>Now that you have some experience with the existing list-processing
|
|
abstractions in ISL, it is time to tackle some of the small projects
|
|
for which you already have programs. The challenge is to look for two
|
|
kinds of improvements. First, inspect the programs for functions that
|
|
traverse lists. For these functions, you already have signatures, purpose
|
|
statements, tests, and working definitions that pass the tests. Change the
|
|
definitions to use abstractions from <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures <span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>. Second, also determine whether there are
|
|
opportunities to create new abstractions. Indeed, you might be able to
|
|
abstract across these classes of programs and provide generalized
|
|
functions that help you write additional programs.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aabstraction-in-dictionaries))"></a><span style="font-weight: bold">Exercise</span> 275. <a href="part_two.html#%28part._sec~3adict%29" data-pltdoc="x">Real-World Data: Dictionaries</a> deals
|
|
with<span class="refelem"><span class="refcolumn"><span class="refcontent">You may wish to tackle these exercises again after
|
|
studying <a href="part_three.html#%28part._ch~3a3lambda%29" data-pltdoc="x">Nameless Functions</a>.</span></span></span> relatively simple tasks relating to English
|
|
dictionaries. The design of two of them just call out for the use of
|
|
existing abstractions:
|
|
</div><div class="SIntrapara"><ul><li><p>Design <span class="RktSym">most-frequent</span>. The function consumes a
|
|
<a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> and produces the <a href="part_two.html#%28tech._letter._count%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter-Count</span></a> for the letter that
|
|
is most frequently used as the first one in the words of the given
|
|
<a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a>.</p></li><li><p>Design <span class="RktSym">words-by-first-letter</span>. The function consumes a
|
|
<a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> and produces a list of <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a>s, one per
|
|
<a href="part_two.html#%28tech._letter%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter</span></a>. Do <span style="font-weight: bold">not</span> include <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> if there are no words
|
|
for some letter; ignore the empty grouping instead.</p></li></ul></div><div class="SIntrapara">For the data definitions, see <a href="part_two.html#%28counter._%28figure._fig~3areading-a-dictionary%29%29" data-pltdoc="x">figure <span class="FigureRef">74</span></a>. <a href="part_three.html#%28counter._%28exercise._ex~3aabstraction-in-dictionaries%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aabstraction-in-itunes))"></a><span style="font-weight: bold">Exercise</span> 276. <a href="part_two.html#%28part._itunes-data._sec~3aitunes%29" data-pltdoc="x">Real-World Data: iTunes</a> explains
|
|
how to analyze the information in an iTunes XML library.
|
|
</div><div class="SIntrapara"><ul><li><p>Design <span class="RktSym">select-album-date</span>. The function consumes the title of
|
|
an album, a date, and an <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. It extracts from the latter the
|
|
list of tracks from the given album that have been played after
|
|
the date.</p></li><li><p>Design <span class="RktSym">select-albums</span>. The function consumes an
|
|
<a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. It produces a list of <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>, one per album. Each
|
|
album is uniquely identified by its title and shows up in the result only
|
|
once.</p></li></ul></div><div class="SIntrapara">See <a href="part_two.html#%28counter._itunes-data._%28figure._fig~3aitunes-api-lists%29%29" data-pltdoc="x">figure <span class="FigureRef">77</span></a> for the services provided by <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span>. <a href="part_three.html#%28counter._%28exercise._ex~3aabstraction-in-itunes%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3aabstractions-in-space-war))"></a><span style="font-weight: bold">Exercise</span> 277. <a href="part_two.html#%28part._sec~3aspace-war%29" data-pltdoc="x">Full Space War</a> spells out a
|
|
game of space war. In the basic version, a UFO descends and a player
|
|
defends with a tank. One additional suggestion is to equip the UFO with
|
|
charges that it can drop at the tank; the tank is destroyed if a charge
|
|
comes close enough.</p><p>Inspect the code of your project for places where it can benefit from
|
|
existing abstraction, that is, processing lists of shots or charges.</p><p>Once you have simplified the code with the use of existing abstractions,
|
|
look for opportunities to create abstractions. Consider moving lists of
|
|
objects as one example where abstraction may pay off. <a href="part_three.html#%28counter._%28exercise._ex~3aabstractions-in-space-war%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aabstractions-in-snake))"></a><span style="font-weight: bold">Exercise</span> 278. <a href="part_two.html#%28part._sec~3aworms%29" data-pltdoc="x">Feeding Worms</a> explains how another
|
|
one of the oldest computer games work. The game features a worm that moves
|
|
at a constant speed in a player-controlled direction. When it encounters
|
|
food, it eats the food and grows. When it runs into the wall or into
|
|
itself, the game is over.</p><p>This project can also benefit from the abstract list-processing functions in
|
|
ISL. Look for places to use them and replace existing code, a piece at
|
|
a time. Tests will ensure that you aren’t introducing mistakes. <a href="part_three.html#%28counter._%28exercise._ex~3aabstractions-in-snake%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>17<tt> </tt><a name="(part._ch~3a3lambda)"></a>Nameless Functions</h3><p><div class="SIntrapara">Using abstract functions needs functions as arguments. Occasionally
|
|
these functions are existing primitive functions, teachpack functions, or
|
|
functions that you defined:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span> creates <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">another-list</span><span class="stt"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span> concatenates the items in <span class="RktSym">a-list</span> and
|
|
<span class="RktSym">another-list</span> into a single list; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._above%29%29" class="RktValLink" data-pltdoc="x">above</a></span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span><span class="stt"> </span><span class="RktSym">images</span><span class="RktPn">)</span> stacks the
|
|
given images.</p></li></ul></div><div class="SIntrapara">At other times, it requires the definition of a simple helper function,
|
|
a definition that often consists of a single line. Consider this use
|
|
of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span>: <a name="(idx._(gentag._445))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">acceptable?</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktSym">acceptable?</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It finds all items on an inventory list whose price is below
|
|
<span class="RktSym">th</span>. The auxiliary function is nearly trivial yet its
|
|
definition takes up three lines.</div></p><p><div class="SIntrapara">This situation calls for an improvement to the language. Programmers should
|
|
be able to create such small and insignificant functions without much
|
|
effort.<span class="refelem"><span class="refcolumn"><span class="refcontent">If you haven’t done so, choose “Intermediate Student
|
|
with <span class="stt">lambda</span>” from the “How to Design Programs” submenu in the
|
|
“Language” menu in DrRacket. The history of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> is intimately involved
|
|
with the early history of programming and programming language
|
|
design.</span></span></span> The next level in our hierarchy of teaching languages,
|
|
“Intermediate Student Language with <span class="stt">lambda</span>,” solves the
|
|
problem with a new concept, nameless functions. This chapter introduces
|
|
the concept: its syntax, its meaning, and its pragmatics. With
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>, the above definition is, conceptually speaking, a
|
|
one-liner:
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._ir%29" class="techoutside" data-pltdoc="x"><span class="techinside">IR</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first two sections focus the mechanics of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>; the
|
|
remaining ones use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> for instantiating abstractions, for
|
|
testing and specifying, and for representing infinite data.</div></p><h4>17.1<tt> </tt><a name="(part._sec~3aint-lambda)"></a>Functions from <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span></h4><p><div class="SIntrapara">The syntax of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> is straightforward:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">variable-1</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktVar">variable-N</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVar">expression</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Its distinguishing characteristic is the keyword <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. The
|
|
keyword is followed by a sequence of variables, enclosed in a pair of
|
|
parentheses. The last piece is an arbitrary expression, and it computes
|
|
the result of the function when it is given values for its parameters.</div></p><p><div class="SIntrapara">Here are three simple examples, all of which consume one argument:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" 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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._expt%29%29" class="RktValLink" data-pltdoc="x">expt</a></span><span class="stt"> </span><span class="RktVal">10</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span>, which assumes that the argument is a
|
|
number and computes the exponent of 10 to the number;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="stt"> </span><span class="RktVal">"To "</span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">","</span><span class="RktPn">)</span><span class="RktPn">)</span>,
|
|
which uses a given string to synthesize an address with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span>; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="stt"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">th</span><span class="RktPn">)</span><span class="RktPn">)</span>, which is a
|
|
function on an <span class="RktSym">IR</span> structure that extracts the price and compares it
|
|
with <span class="RktSym">th</span>.</p></li></ol></div></p><p><div class="SIntrapara">One way to understand how <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> works is to view it as an
|
|
abbreviation for a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression. For example,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">is short for<span class="refelem"><span class="refcolumn"><span class="refcontent">This way of thinking about <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> shows
|
|
one more time why the rule for computing with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> is complicated.</span></span></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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">some-name</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</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="hspace"> </span><span class="RktSym">some-name</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This “trick” works, in general, as long as <span class="RktSym">some-name</span> does
|
|
not appear in the body of the function. What this means is that
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> creates a function with a name that nobody knows. If
|
|
nobody knows the name, it might as well be nameless.</div></p><p><div class="SIntrapara">To use a function created from a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression, you apply it
|
|
to the correct number of arguments. It works as expected:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._expt%29%29" class="RktValLink" data-pltdoc="x">expt</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">100</span></p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktVal">"Robby"</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktVal">"etc."</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">"Robby, etc."</span></p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Note how the second sample function requires two arguments and that the
|
|
last example assumes a definition for <span class="RktSym">th</span> in the definitions
|
|
window such as this one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">th</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The result of the last example is <span class="RktVal">#true</span> because the price field of
|
|
the inventory record contains <span class="RktVal">10</span>, and <span class="RktVal">10</span> is less than
|
|
<span class="RktVal">20</span>.</div></p><p><div class="SIntrapara">The important point is that these nameless functions can be used
|
|
wherever a function is required, including with the abstractions from
|
|
<a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figure <span class="FigureRef">95</span></a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._expt%29%29" class="RktValLink" data-pltdoc="x">expt</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list 10 100 1000)</span></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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktVal">"etc."</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"Matthew"</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">"Robby, Matthew, etc."</span></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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">33</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (make-IR ...))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Once<span class="refelem"><span class="refcolumn"><span class="refcontent">The dots are <span style="font-weight: bold">not</span> part of the output.</span></span></span>
|
|
again, the last example assumes a definition for <span class="RktSym">th</span>.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alambda1))"></a><span style="font-weight: bold">Exercise</span> 279. Decide which of the following phrases are legal
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expressions:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" 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></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Explain why they are legal or illegal. If in doubt, experiment in the
|
|
interactions area of DrRacket. <a href="part_three.html#%28counter._%28exercise._ex~3alambda1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alambda3))"></a><span style="font-weight: bold">Exercise</span> 280. Calculate the result of the following expressions:
|
|
</div><div class="SIntrapara"><ol><li><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk" style="display: inline-table; vertical-align: text-top; margin-top: 0;"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" 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><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></li><li><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk" style="display: inline-table; vertical-align: text-top; margin-top: 0;"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">y</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">x</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="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></li><li><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk" style="display: inline-table; vertical-align: text-top; margin-top: 0;"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">z</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">z</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">y</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="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></li></ol></div><div class="SIntrapara">Check your results in DrRacket. <a href="part_three.html#%28counter._%28exercise._ex~3alambda3%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alambda0))"></a><span style="font-weight: bold">Exercise</span> 281. Write down a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression that
|
|
</div><div class="SIntrapara"><ol><li><p>consumes a number and decides whether it is less than <span class="RktVal">10</span>;</p></li><li><p>multiplies two given numbers and turns the result into a string;</p></li><li><p>consumes a natural number and returns <span class="RktVal">0</span> for evens and
|
|
<span class="RktVal">1</span> for odds;</p></li><li><p>consumes two inventory records and compares them by price; and</p></li><li><p>adds a red dot at a given <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> to a given <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>.</p></li></ol></div><div class="SIntrapara">Demonstrate how to use these functions in the interactions area. <a href="part_three.html#%28counter._%28exercise._ex~3alambda0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>17.2<tt> </tt><a name="(part._sec~3alambda-technical)"></a>Computing with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span></h4><p>The insight that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> abbreviates a certain kind of
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> also connects constant definitions and function
|
|
definitions. Instead of viewing function definitions as given, we
|
|
can take <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>s as another fundamental
|
|
concept and say that a function definition abbreviates a plain constant
|
|
definition with a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression on the right-hand side.</p><p><div class="SIntrapara">It’s best to look at some concrete examples:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><p>is short for</p></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">What this line says is that a function definition consists of two steps:
|
|
the creation of the function and its naming. Here, the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> on
|
|
the right-hand side creates a function of one argument <span style="font-style: italic">x</span> that
|
|
computes <img src="pict_124.png" alt="image" width="27" height="8"/>; it is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span> that names the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression <span class="RktSym">f</span>. We give names to functions for
|
|
two distinct reasons. On the one hand, a function is often called more than
|
|
once from other functions, and we wouldn’t want to spell out the function
|
|
with a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> each time it is called. On the other hand,
|
|
functions are often recursive because they process recursive forms of
|
|
data, and naming functions makes it easy to create recursive functions.</div></p><p><a name="(counter._(exercise._ex~3alambda-technical0))"></a><span style="font-weight: bold">Exercise</span> 282. Experiment with the above definitions in
|
|
DrRacket.</p><p><div class="SIntrapara">Also add <a name="(idx._(gentag._446))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">compare</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f-plain</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f-lambda</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">to the definitions area after renaming the left-hand <span class="RktSym">f</span> to
|
|
<span class="RktSym">f-plain</span> and the right-hand one to <span class="RktSym">f-lambda</span>. Then run
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">compare</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace"> </span><span class="RktVal">100000</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">a few times to make sure the two functions agree on all kinds of inputs. <a href="part_three.html#%28counter._%28exercise._ex~3alambda-technical0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">If function definitions are just abbreviations for constant definitions, we
|
|
can replace the function name by its <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktVal">42</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">42</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Strangely though, this substitution appears to create an expression that
|
|
violates the grammar as we know it. To be precise, it generates an
|
|
application expression whose function position <span style="font-weight: bold">is</span> a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression.</div></p><p><div class="SIntrapara">The point is that ISL+’s grammar differs from ISL’s in <span style="font-weight: bold">two</span> aspects: it
|
|
obviously comes with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expressions, but it also allows
|
|
arbitrary expressions to show up in the function position of an
|
|
application. This means that you may need to evaluate the function
|
|
position before you can proceed with an application, but you know how to
|
|
evaluate most expressions. Of course, the real difference is that the
|
|
evaluation of an expression may yield a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>
|
|
expression. Functions really are values. The following grammar revises
|
|
the one from <a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a> to summarize these differences:
|
|
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td align="right" valign="baseline"><span class="hspace"> </span><span class="RktVar">expr</span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktSym">...</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktVar">expr</span><span class="hspace"> </span><span class="RktVar">expr</span><span class="hspace"> </span><span class="RktSym">...</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td></tr><tr><td align="right" valign="baseline"><span class="hspace"> </span><span class="RktVar">value</span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktSym">...</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">variable</span><span class="hspace"> </span><span class="RktVar">variable</span><span class="hspace"> </span><span class="RktSym">...</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVar">expr</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Alonzo Church, who invented <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> in the late
|
|
1920s, hoped to create a unifying theory of functions. He stated the
|
|
<span style="font-style: italic">beta</span> axiom roughly like this.—<wbr></wbr>From his work we
|
|
know that from a theoretical perspective, a language does not need
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> once it has <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. But the margin of this page is
|
|
too small to explain this idea properly. If you are curious, read up on
|
|
<a href="Https://felleisen.org/matthias/BTLS-sample.pdf">the
|
|
<span style="font-weight: bold">Y</span> combinator</a>.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">What you really need to know is how to evaluate the application of a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression to arguments, and that is surprisingly
|
|
straightforward:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x-1</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">x-n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">f-body</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">v-1</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">v-n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktSym">f-body</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">with all occurrences of </span><span class="RktSym">x-1</span><span class="RktCmt"> </span>...<span class="RktCmt"> </span><span class="RktSym">x-n</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">replaced with </span><span class="RktSym">v-1</span><span class="RktCmt"> </span>...<span class="RktCmt"> </span><span class="RktSym">v-n</span><span class="RktCmt">, respectively [beta-v]</span></td></tr></table></blockquote></div><div class="SIntrapara">That is, the application of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expression proceeds just
|
|
like that of an ordinary function. We replace the parameters of the
|
|
function with the actual argument values and compute the value of the
|
|
function body.</div></p><p><div class="SIntrapara">Here is how to use this law on the first example in this chapter:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktVal">20</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The second one proceeds in an analogous manner:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">"etc."</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktVal">"etc."</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktVal">"Robby, etc."</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Use your intuition to calculate the third example:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Assume <span class="RktSym">th</span> is larger than or equal to <span class="RktVal">10</span>.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aeval-lambda1))"></a><span style="font-weight: bold">Exercise</span> 283. Confirm that DrRacket’s stepper can deal with
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. Use it to step through the third example and also to determine
|
|
how DrRacket evaluates the following expressions:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktSym">rst</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"etc."</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"Matthew"</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="RktVal">)</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">IR-price</span><span class="hspace"> </span><span class="RktSym">ir</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">th</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"bear"</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-IR</span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="hspace"> </span><span class="RktVal">33</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><a href="part_three.html#%28counter._%28exercise._ex~3aeval-lambda1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aeval-lambda3))"></a><span style="font-weight: bold">Exercise</span> 284. Step through the evaluation of this expression:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">Now step through this one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Stop! What do you think we should try next?</div></p><p><div class="SIntrapara">Yes, try to evaluate
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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">x</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Be ready to hit <span class="emph">STOP</span>. <a href="part_three.html#%28counter._%28exercise._ex~3aeval-lambda3%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>17.3<tt> </tt><a name="(part._sec~3alambda)"></a>Abstracting with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span></h4><p><div class="SIntrapara">Although it may take you a while to get used to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> notation, you’ll
|
|
soon notice that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> makes short functions much more
|
|
readable than <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> definitions. Indeed, you will find that you
|
|
can adapt step 4 of the design recipe from
|
|
<a href="part_three.html#%28part._sec~3adesigning-with-abstraction%29" data-pltdoc="x">Designing with Abstractions</a> to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> instead of
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. Consider the running example from that section. Its
|
|
template based on <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> is this: <a name="(idx._(gentag._447))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktSym">add-one-dot</span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you spell out the parameters so that their names include signatures,
|
|
you can easily pack all the information from <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> into a single
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">a-posn</span><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">From here, you should be able to complete the definition as well as you
|
|
did from the original template:</div></p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dots</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">a-posn</span><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">DOT</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">a-posn</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">a-posn</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">scene</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p><div class="SIntrapara">Let’s illustrate <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> with some more examples from
|
|
<a href="part_three.html#%28part._sec~3ausage-examples%29" data-pltdoc="x">Using Abstractions, by Example</a>:
|
|
</div><div class="SIntrapara"><ul><li><p><div class="SIntrapara">the purpose of the first function is to add <span class="RktVal">3</span> to each
|
|
x-coordinate on a given list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s: <a name="(idx._(gentag._448))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-3-to-all</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Because <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> expects a function of one argument, we clearly want
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span>. The function then deconstructs <span class="RktSym">p</span>, adds
|
|
<span class="RktVal">3</span> to the x-coordinate, and repackages the data into a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p></li><li><p><div class="SIntrapara">the second one eliminates <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s whose y-coordinate is
|
|
above <span class="RktVal">100</span>: <a name="(idx._(gentag._449))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keep-good</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">100</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Here we know that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> needs a function of one argument that
|
|
produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>. First, the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> function extracts
|
|
the y-coordinate from the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> to which <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> applies
|
|
the function. Second, it checks whether it is less than or equal to
|
|
<span class="RktVal">100</span>, the desired limit.</div></p></li><li><p><div class="SIntrapara">and the third one determines whether any <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> on <span class="RktSym">lop</span>
|
|
is close to some given point: <a name="(idx._(gentag._450))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close?</span><span class="hspace"> </span><span class="RktSym">lop</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">close-to</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">pt</span><span class="hspace"> </span><span class="RktSym">CLOSENESS</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">lop</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like the preceding two examples, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> is a function that expects
|
|
a function of one argument and applies this functional argument to every
|
|
item on the given list. If any result is <span class="RktVal">#true</span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span>
|
|
returns <span class="RktVal">#true</span>, too; if all results are <span class="RktVal">#false</span>,
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> produces <span class="RktVal">#false</span>.</div></p></li></ul></div><div class="SIntrapara">It is best to compare the definitions from
|
|
<a href="part_three.html#%28part._sec~3ausage-examples%29" data-pltdoc="x">Using Abstractions, by Example</a> and the definitions above side by
|
|
side. When you do so, you should notice how easy the transition from
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> is and how concise the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>
|
|
version is in comparison to the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> version. Thus, if you are
|
|
ever in doubt, design with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> first and then convert this
|
|
tested version into one that uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. Keep in mind, however,
|
|
that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> is not a cure-all. The locally defined function comes
|
|
with a name that explains its purpose, and, if it is long, the use of an
|
|
abstraction with a named function is much easier to understand than one
|
|
with a large <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>.</div></p><p>The following exercises request that you solve the problems from
|
|
<a href="part_three.html#%28part._sec~3aabstraction-exercises%29" data-pltdoc="x">Finger Exercises: Abstraction</a> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> in ISL+ .</p><p><a name="(counter._(exercise._ex~3a2use-map))"></a><span style="font-weight: bold">Exercise</span> 285. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> to define the function
|
|
<span class="RktSym">convert-euro</span>, which converts a list of US$ amounts into a
|
|
list of € amounts based on an exchange rate of US$<span style="font-style: italic"></span>1<span style="font-style: italic">.</span>0<span style="font-style: italic"></span>6<span style="font-style: italic"></span> per
|
|
€.</p><p>Also use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> to define <span class="RktSym">convertFC</span>, which converts a list
|
|
of Fahrenheit measurements to a list of Celsius measurements.</p><p>Finally, try your hand at <span class="RktSym">translate</span>, a function that translates a
|
|
list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s into a list of lists of pairs of numbers. <a href="part_three.html#%28counter._%28exercise._ex~3a2use-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3a2sort-abstract))"></a><span style="font-weight: bold">Exercise</span> 286. An inventory record specifies the name of an
|
|
inventory item, a description, the acquisition price, and the recommended sales price.</p><p>Define a function that sorts a list of inventory records by the difference
|
|
between the two prices. <a href="part_three.html#%28counter._%28exercise._ex~3a2sort-abstract%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3a2use-filter))"></a><span style="font-weight: bold">Exercise</span> 287. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> to define
|
|
<span class="RktSym">eliminate-exp</span>. The function consumes a number, <span class="RktSym">ua</span>, and a
|
|
list of inventory records (containing name and price), and it produces a list
|
|
of all those structures whose acquisition price is below <span class="RktSym">ua</span>.</p><p>Then use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> to define <span class="RktSym">recall</span>, which consumes the name
|
|
of an inventory item, called <span class="RktSym">ty</span>, and a list of inventory records and which
|
|
produces a list of inventory records that do not use the name <span class="RktSym">ty</span>.</p><p>In addition, define <span class="RktSym">selection</span>, which consumes two lists of names
|
|
and selects all those from the second one that are also on the first. <a href="part_three.html#%28counter._%28exercise._ex~3a2use-filter%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3a2build-list1))"></a><span style="font-weight: bold">Exercise</span> 288. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> to
|
|
define a function that
|
|
</div><div class="SIntrapara"><ol><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">0</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">n</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span> for any natural number
|
|
<span class="RktSym">n</span>;</p></li><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">1</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktMeta"></span> for any natural number <span class="RktSym">n</span>;</p></li><li><p>creates the list <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1/2</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span style="font-style: italic"></span>1<span style="font-style: italic">/n</span><span class="RktPn">)</span> for any natural number <span class="RktSym">n</span>;</p></li><li><p>creates the list of the first <span class="RktSym">n</span> even numbers; and</p></li><li><p>creates a diagonal square of <span class="RktVal">0</span>s and <span class="RktVal">1</span>s; see <a href="part_three.html#%28counter._%28exercise._ex~3alocal-for-diagonal%29%29" data-pltdoc="x">exercise 262</a>.</p></li></ol></div><div class="SIntrapara">Also define <span class="RktSym">tabulate</span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3a2build-list1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3a2and-or-map))"></a><span style="font-weight: bold">Exercise</span> 289. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> to define
|
|
<span class="RktSym">find-name</span>. The function consumes a name and a list of names. It
|
|
determines whether any of the names on the latter are equal to or an
|
|
extension of the former.</p><p>With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> you can define a function that checks all names on a
|
|
list of names that start with the letter <span class="RktVal">"a"</span>.</p><p>Should you use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> to define a function that
|
|
ensures that no name on some list exceeds some given width?
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3a2and-or-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3a2fold-append))"></a><span style="font-weight: bold">Exercise</span> 290. Recall that the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span> function in
|
|
ISL concatenates the items of two lists or, equivalently, replaces
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> at the end of the first list with the second 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> to define <span class="RktSym">append-from-fold</span>. What happens if you
|
|
replace <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>?</div></p><p>Now use one of the fold functions to define functions that compute the sum
|
|
and the product, respectively, of a list of numbers.</p><p>With one of the fold functions, you can define a function that horizontally
|
|
composes a list of <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>s. <span style="font-weight: bold">Hints</span> (1) Look up <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span>. Can you use the other fold function? Also define a
|
|
function that stacks a list of images vertically. (2) Check for
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._above%29%29" class="RktValLink" data-pltdoc="x">above</a></span> in the teachpacks. <a href="part_three.html#%28counter._%28exercise._ex~3a2fold-append%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3a2fold-map))"></a><span style="font-weight: bold">Exercise</span> 291. The fold functions are so powerful that you can
|
|
define almost any list-processing functions with them. Use <span class="RktSym">fold</span> to
|
|
define <span class="RktSym">map-via-fold</span>, which simulates <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>. <a href="part_three.html#%28counter._%28exercise._ex~3a2fold-map%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>17.4<tt> </tt><a name="(part._sec~3aspecification)"></a>Specifying with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span></h4><p><a href="part_three.html#%28counter._%28figure._fig~3asort-local%29%29" data-pltdoc="x">Figure <span class="FigureRef">99</span></a> shows a generalized sorting function that
|
|
consumes a list of values and a comparison function for such values. For
|
|
convenience, <a href="part_three.html#%28counter._%28figure._fig~3ageneral-sort%29%29" data-pltdoc="x">figure <span class="FigureRef">103</span></a> reproduces the essence of the
|
|
definition. The body of <span class="RktSym">sort-cmp</span> introduces two
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> auxiliary functions: <span class="RktSym">isort</span> and <span class="RktSym">insert</span>.
|
|
In addition, the figure also comes with two test cases that illustrate the
|
|
workings of <span class="RktSym">sort-cmp</span>. One demonstrates how the function works on
|
|
strings and the other one on numbers.</p><p><div class="SIntrapara"><a name="(idx._(gentag._451))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [X X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">sorts </span><span class="RktSym">alon0</span><span class="RktCmt"> according to cmp</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktVal">)</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktSym">alon0</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a variant of </span><span class="RktSym">alon</span><span class="RktCmt"> sorted by </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">isort</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">X [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">inserts </span><span class="RktSym">n</span><span class="RktCmt"> into the sorted list of numbers </span><span class="RktSym">alon</span><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</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">isort</span><span class="hspace"> </span><span class="RktSym">alon0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3ageneral-sort))" x-target-lift="Figure"></a>Figure 103: </span>A general sorting function</span></p></blockquote></div></p><p><div class="SIntrapara">Now take a quick look at <a href="part_two.html#%28counter._%28exercise._ex~3asort0%29%29" data-pltdoc="x">exercise 186</a>. It asks you to formulate
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> tests for <span class="RktSym">sort></span> using the
|
|
<span class="RktSym">sorted>?</span> predicate. <a name="(idx._(gentag._452))"></a>
|
|
The former is a function that sorts lists of numbers in descending order;
|
|
the latter is a function that determines whether a list of numbers is
|
|
sorted in descending order. Hence, the solution of this exercise is
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">sorted>?</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">sorted>?</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">sorted>?</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">sorted>?</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The question is how to reformulate the tests for <span class="RktSym">sort-cmp</span>
|
|
analogously.</div></p><p><div class="SIntrapara">Since <span class="RktSym">sort-cmp</span> consumes a comparison function together with a
|
|
list, the generalized version of <span class="RktSym">sorted>?</span> must take one too. If
|
|
so, the following test cases might look like this:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" 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">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Both <span class="RktPn">(</span><span class="RktSym">sorted</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym">sorted</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span> must produce
|
|
predicates. The first one checks whether some list of strings is sorted
|
|
according to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span>, and the second one whether a list of
|
|
numbers is sorted via <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span>.</div></p><p><div class="SIntrapara">We have thus worked out the desired signature and purpose of <span class="RktSym">sorted</span>:
|
|
</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">[X] [X X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] -> [[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a function that determines whether </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">some list is sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">What we need to do now is to go through the rest of the design process.</div></p><p><div class="SIntrapara">Let’s first finish the header. Remember that the header produces a value
|
|
that matches the signature and is likely to break most of the
|
|
tests/examples. Here we need <span class="RktSym">sorted</span> to produce a function that
|
|
consumes a list and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>. With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>,
|
|
that’s actually straightforward:<a name="(idx._(gentag._453))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! This is your first function-producing function. Read the
|
|
definition again. Can you explain this definition in your own words?</div></p><p><div class="SIntrapara">Next we need examples. According to our above analysis,
|
|
<span class="RktSym">sorted</span> consumes predicates such as <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span>, but clearly, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">></a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span>, and your own comparison
|
|
functions should be acceptable, too. At first glance, this suggests test
|
|
cases of the shape
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">But, <span class="RktPn">(</span><span class="RktSym">sorted</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span> produces a function, and, according to
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3asem2-funcs%29%29" data-pltdoc="x">exercise 245</a>, it impossible to compare functions.</div></p><p><div class="SIntrapara">Hence, to formulate reasonable test cases, we need to apply the result of
|
|
<span class="RktPn">(</span><span class="RktSym">sorted</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span> to appropriate lists. And, based on this insight,
|
|
the test cases almost formulate themselves; indeed, they can easily be
|
|
derived from those for <span class="RktSym">sort-cmp</span> in <a href="part_three.html#%28counter._%28figure._fig~3ageneral-sort%29%29" data-pltdoc="x">figure <span class="FigureRef">103</span></a>:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="RktVal">)</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktVal">)</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><span style="font-weight: bold">Note</span> Using square instead of parentheses highlights that the first
|
|
expression produces a function, which is then applied to arguments.</div></p><p><div class="SIntrapara">From this point on, the design is quite conventional. What we basically
|
|
wish to design is a generalization of <span class="RktSym">sorted>?</span> from
|
|
<a href="part_two.html#%28part._sec~3alists~3ane%29" data-pltdoc="x">Non-empty Lists</a>; let’s call this function <span class="RktSym">sorted/l</span>. What
|
|
is unusual about <span class="RktSym">sorted/l</span> is that it “lives” in the body of a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> inside of <span class="RktSym">sorted</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted/l</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Even though <span class="RktSym">sorted/l</span> is defined locally, it must refer to <span class="RktSym">cmp</span>.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asorted-curried))"></a><span style="font-weight: bold">Exercise</span> 292. Design the function <span class="RktSym">sorted?</span>, which
|
|
comes with the following signature and purpose statement:
|
|
</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">[X X -> </span><span style="font-style: italic">Boolean</span><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._nelist._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktSym">l</span><span class="RktCmt"> is sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted?</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted?</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted?</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The wish list even includes examples. <a href="part_three.html#%28counter._%28exercise._ex~3asorted-curried%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a href="part_three.html#%28counter._%28figure._fig~3ageneral-sorted%29%29" data-pltdoc="x">Figure <span class="FigureRef">104</span></a> shows the result of the <a name="(idx._(gentag._454))"></a>design process. The
|
|
<span class="RktSym">sorted</span> function consumes a comparison function <span class="RktSym">cmp</span> and
|
|
produces a predicate. The latter consumes a list <span class="RktSym">l0</span> and uses a
|
|
locally defined function to determine whether all the items in
|
|
<span class="RktSym">l0</span> are ordered via <span class="RktSym">cmp</span>. Specifically, the locally defined
|
|
function checks a non-empty list; in the body of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>,
|
|
<span class="RktSym">sorted</span> first checks whether <span class="RktSym">l0</span> is empty, in which case it
|
|
simply produces <span class="RktVal">#true</span> because the empty list is sorted.</p><p>Stop! Could you redefine <span class="RktSym">sorted</span> to use <span class="RktSym">sorted?</span> from
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3asorted-curried%29%29" data-pltdoc="x">exercise 292</a>? Explain why <span class="RktSym">sorted/l</span> does not consume
|
|
<span class="RktSym">cmp</span> as an argument.</p><p><div class="SIntrapara"><a name="(idx._(gentag._455))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[X X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] -> [[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is the given list </span><span class="RktSym">l0</span><span class="RktCmt"> sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._nelist._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is </span><span class="RktSym">l</span><span class="RktCmt"> sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted/l</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</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">sorted/l</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted/l</span><span class="hspace"> </span><span class="RktSym">l0</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></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3ageneral-sorted))" x-target-lift="Figure"></a>Figure 104: </span>A curried predicate for checking the ordering of a list</span></p></blockquote></div></p><p>The <span class="RktSym">sorted</span> function in <a href="part_three.html#%28counter._%28figure._fig~3ageneral-sorted%29%29" data-pltdoc="x">figure <span class="FigureRef">104</span></a> is a
|
|
<span style="font-style: italic">curried</span> version of a function that consumes two
|
|
arguments:<span class="refelem"><span class="refcolumn"><span class="refcontent">The verb “curry” honors Haskell Curry, the
|
|
second person to invent the idea. The first one was Moses Schönfinkel.</span></span></span>
|
|
<span class="RktSym">cmp</span> and <span class="RktSym">l0</span>. Instead of consuming two arguments at once,
|
|
a curried function consumes one argument and then returns a function that
|
|
consumes the second one.</p><p><div class="SIntrapara"><a href="part_two.html#%28counter._%28exercise._ex~3asort0%29%29" data-pltdoc="x">Exercise 186</a> asks how to formulate a test case that exposes
|
|
mistakes in sorting functions. Consider this definition: <a name="(idx._(gentag._456))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a sorted version of </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp/bad</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Formulating such a test case with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> is straightforward.</div></p><p>To design a predicate that exposes <span class="RktSym">sort-cmp/bad</span> as flawed, we need
|
|
to understand the purpose of <span class="RktSym">sort-cmp</span> or sorting in general. It
|
|
clearly is unacceptable to throw away the given list and to produce some
|
|
other list in its place. That’s why the purpose statement of
|
|
<span class="RktSym">isort</span> says that the function “produces a <span style="font-weight: bold">variant</span> of” the
|
|
given list. “Variant” means that the function does not throw away any of
|
|
the items on the given list.</p><p><div class="SIntrapara">With these thoughts in mind, we can now say that we want a predicate that
|
|
checks whether the result is sorted <span style="font-weight: bold">and</span> contains all the items from
|
|
the given list:<a name="(idx._(gentag._457))"></a>
|
|
</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">[X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [X X -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">] -> [[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is </span><span class="RktSym">l0</span><span class="RktCmt"> sorted according to </span><span class="RktSym">cmp</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">are all items in list </span><span class="RktSym">k</span><span class="RktCmt"> members of list </span><span class="RktSym">l0</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The two lines of the purpose statement suggest examples:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like <span class="RktSym">sorted</span>, <span class="RktSym">sorted-variant-of</span> consumes arguments and
|
|
produces a function. For the first case, <span class="RktSym">sorted-variant-of</span>
|
|
produces <span class="RktVal">#true</span> because the <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktVal">)</span> is sorted and it
|
|
contains all numbers in <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span>. In contrast, the function
|
|
produces <span class="RktVal">#false</span> in the second case because <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="RktVal">)</span> lacks
|
|
<span class="RktVal">2</span> from the originally given list.</div></p><p><div class="SIntrapara">A two-line purpose statement suggests two tasks, and two tasks means that
|
|
the function itself is a combination of two functions: <a name="(idx._(gentag._458))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted?</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="hspace"> </span><span class="RktSym">l0</span><span class="hspace"> </span><span class="RktSym">k</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">The body of the function is an <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span> expression that combines two
|
|
function calls. With the call to the <span class="RktSym">sorted?</span> function from
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3asorted-curried%29%29" data-pltdoc="x">exercise 292</a>, the function realizes the first line of the
|
|
purpose statement. The second call, <span class="RktPn">(</span><span class="RktSym">contains?</span><span class="stt"> </span><span class="RktSym">l0</span><span class="stt"> </span><span class="RktSym">k</span><span class="RktPn">)</span>, is an
|
|
implicit wish for an auxiliary function.</div></p><p><div class="SIntrapara">We immediately give the full definition: <a name="(idx._(gentag._459))"></a>
|
|
</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">[X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> Boolean </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">are all items in list </span><span class="RktSym">k</span><span class="RktCmt"> members of list </span><span class="RktSym">l</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</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">4</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktVal">)</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">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">in-k</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktSym">in-k</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">On the one hand, we have never explained how to systematically design a
|
|
function that consumes two lists, and it actually needs its own chapter;
|
|
see <a href="part_four.html#%28part._ch~3asimu%29" data-pltdoc="x">Simultaneous Processing</a>. On the other hand, the function
|
|
definition clearly satisfies the purpose statement. The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span>
|
|
expression checks that every item in <span class="RktSym">k</span> is a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span> of
|
|
<span class="RktSym">l</span>, which is what the purpose statement promises.</div></p><p><div class="SIntrapara">Sadly, <span class="RktSym">sorted-variant-of</span> fails to describe sorting functions
|
|
properly. Consider this variant of a sorting function: <a name="(idx._(gentag._460))"></a>
|
|
</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a sorted version of </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp/worse</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">sorted</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It is again easy to expose a flaw in this function with a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> test that it ought to pass but clearly fails:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp/worse</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Surprisingly, a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> test based on
|
|
<span class="RktSym">sorted-variant-of</span> succeeds: <a name="(idx._(gentag._461))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp/worse</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of</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">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Indeed, such a test succeeds for any list of numbers, not just
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktVal">)</span>, because the predicate generator merely
|
|
checks that all the items on the original list are members of the
|
|
resulting list; it fails to check whether all items on the
|
|
resulting list are also members of the original list.</div></p><p><div class="SIntrapara">The easiest way to add this third check to <span class="RktSym">sorted-variant-of</span> is to
|
|
add a third sub-expression to the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span> expression: <a name="(idx._(gentag._462))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of.v2</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted?</span><span class="hspace"> </span><span class="RktSym">cmp</span><span class="hspace"> </span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="stt"> </span><span class="RktSym">l0</span><span class="stt"> </span><span class="RktSym">k</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains?</span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym">l0</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">We choose to reuse <span class="RktSym">contains?</span> but with its arguments flipped.</div></p><p><div class="SIntrapara">At this point, you may wonder why we are bothering with the development of
|
|
such a predicate when we can rule out bad sorting functions with plain
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> tests. The difference is that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span>
|
|
checks only that our sorting functions work on specific lists. With a
|
|
predicate such as <span class="RktSym">sorted-variant-of.v2</span>, we can articulate the claim
|
|
that a sorting function works for all possible inputs:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">build-list-of-random-numbers</span><span class="hspace"> </span><span class="RktVal">500</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort-cmp</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of.v2</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Let’s take a close look at these two lines. The first line generates a
|
|
list of 500 numbers. Every time you ask DrRacket to evaluate this
|
|
test, it is likely to generate a list never seen before. The second line
|
|
is a test case that says sorting this generated list produces a
|
|
list that (1) is sorted, (2) contains all the numbers on the
|
|
generated list, and (3) contains nothing else. In other words, it is
|
|
almost like saying that <span style="font-weight: bold">for all</span> possible lists, <span class="RktSym">sort-cmp</span>
|
|
produces outcomes that <span class="RktSym">sorted-variant-of.v2</span> blesses.</div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>The specification is still flawed if the given list contains
|
|
duplicate elements. Construct two list of numbers—<wbr></wbr>call them <span class="RktSym">l1</span>
|
|
and <span class="RktSym">l2</span>—<wbr></wbr>such that <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="stt"> </span><span class="RktSym">l1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">sorted-variant-of.v2</span><span class="stt"> </span><span class="RktSym">l2</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="RktPn">)</span><span class="RktPn">)</span> yields <span class="RktVal">#true</span>. We thank Atharva
|
|
Shukla for suggesting this exercise.</p></blockquote></blockquote></blockquote><p>Computer scientists call <span class="RktSym">sorted-variant-of.v2</span> a
|
|
<span style="font-style: italic">specification</span> of a sorting function. The idea that <span style="font-weight: bold">all</span>
|
|
lists of numbers pass the above test case is a <span style="font-weight: bold">theorem</span> about the
|
|
relationship between the specification of the sorting function and its
|
|
implementation. If a programmer can prove this theorem with a mathematical
|
|
argument, we say that the function is <span style="font-weight: bold">correct</span> with respect to its
|
|
specification. How to prove functions or programs correct is beyond the
|
|
scope of this book, but a good computer science curriculum shows you in a
|
|
follow-up course how to construct such proofs.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aspec1))"></a><span style="font-weight: bold">Exercise</span> 293. Develop <span class="RktSym">found?</span>, a specification for the
|
|
<span class="RktSym">find</span> function: <a name="(idx._(gentag._463))"></a>
|
|
</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">[X] X [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">returns the first sublist of </span><span class="RktSym">l</span><span class="RktCmt"> that starts</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">with </span><span class="RktSym">x</span><span class="RktCmt">, </span><span class="RktVal">#false</span><span class="RktCmt"> otherwise</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">x</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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">Use <span class="RktSym">found?</span> to formulate a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> test for
|
|
<span class="RktSym">find</span>. <a name="(idx._(gentag._464))"></a> <a href="part_three.html#%28counter._%28exercise._ex~3aspec1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aspec2))"></a><span style="font-weight: bold">Exercise</span> 294. Develop <span class="RktSym">is-index?</span>, a specification for <span class="RktSym">index</span>:
|
|
<a name="(idx._(gentag._465))"></a>
|
|
</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">[X] X [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -> [</span><a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determine the index of the first occurrence</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">of </span><span class="RktSym">x</span><span class="RktCmt"> in </span><span class="RktSym">l</span><span class="RktCmt">, </span><span class="RktVal">#false</span><span class="RktCmt"> otherwise</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">index</span><span class="hspace"> </span><span class="RktSym">x</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" 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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">index</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">1</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">Use <span class="RktSym">is-index?</span> to formulate a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> test for
|
|
<span class="RktSym">index</span>. <a name="(idx._(gentag._466))"></a> <a href="part_three.html#%28counter._%28exercise._ex~3aspec2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aspec0))"></a><span style="font-weight: bold">Exercise</span> 295. Develop <span class="RktSym">n-inside-playground?</span>, a
|
|
specification of the <span class="RktSym">random-posns</span> function below. The
|
|
function generates a predicate that ensures
|
|
that the length of the given list is some given count and that all <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s
|
|
in this list are within a <span class="RktSym">WIDTH</span> by <span class="RktSym">HEIGHT</span> rectangle:
|
|
<a name="(idx._(gentag._467))"></a>
|
|
<a name="(idx._(gentag._468))"></a>
|
|
</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">distances in terms of pixels </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktVal">300</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">300</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><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">generates </span><span class="RktSym">n</span><span class="RktCmt"> random </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">s in [0,</span><span class="RktSym">WIDTH</span><span class="RktCmt">) by [0,</span><span class="RktSym">HEIGHT</span><span class="RktCmt">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">random-posns</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">n-inside-playground?</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">random-posns</span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">n</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">i</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</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>Define <span class="RktSym">random-posns/bad</span> that satisfies
|
|
<span class="RktSym">n-inside-playground?</span> and does not live up to the expectations
|
|
implied by the above purpose statement. <span style="font-weight: bold">Note</span> This specification is
|
|
<span style="font-weight: bold">incomplete</span>. Although the word “partial” might come to mind,
|
|
computer scientists reserve the phrase “partial specification” for a
|
|
different purpose. <a href="part_three.html#%28counter._%28exercise._ex~3aspec0%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>17.5<tt> </tt><a name="(part._sec~3alambda.I.I)"></a>Representing with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span></h4><p>Because functions are first-class values in ISL+, we may think of them
|
|
as another form of data and use them for data representation. This section
|
|
provides a taste of this idea; the next few chapters do not rely on
|
|
it.</p><p><div class="SIntrapara">As always, we start from a representative problem:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Navy strategists represent fleets of<span class="refelem"><span class="refcolumn"><span class="refcontent">This
|
|
problem is also solvable with a self-referential data representation that
|
|
says a shape is a circle, a rectangle, or a combination of two
|
|
shapes. See the next part of the book for this design choice.</span></span></span> ships as
|
|
rectangles (the ships themselves) and circles (their weapons’ reach). The
|
|
coverage of a fleet of ships is the combination of all these shapes.
|
|
Design a data representation for rectangles, circles, and combinations of
|
|
shapes. Then design a function that determines whether some point is
|
|
within a shape.</p></blockquote></div><div class="SIntrapara">The problem comes with all kinds of concrete interpretations, which we
|
|
leave out here. A slightly more complex version was the subject of a
|
|
programming competition in the mid-1990s run by Yale University on behalf
|
|
of the US Department of Defense.</div></p><p><div class="SIntrapara">One mathematical approach considers shapes as predicates on points. That
|
|
is, a shape is a function that maps a Cartesian point to a Boolean
|
|
value. Let’s translate these English words into a <a name="(idx._(gentag._469))"></a>data definition:
|
|
</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">A </span><a name="(tech._shape)"></a><span style="font-style: italic">Shape</span><span class="RktCmt"> is a function: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> if </span><span class="RktSym">s</span><span class="RktCmt"> is a shape and </span><span class="RktSym">p</span><span class="RktCmt"> a </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">, </span><span class="RktPn">(</span><span class="RktSym">s</span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces </span><span class="RktVal">#true</span><span class="RktCmt"> if </span><span class="RktSym">p</span><span class="RktCmt"> is in </span><span class="RktSym">s</span><span class="RktCmt">, </span><span class="RktVal">#false</span><span class="RktCmt"> otherwise</span></td></tr></table></blockquote></div><div class="SIntrapara">Its interpretation part is extensive because this data representation is
|
|
so unusual. Such an unusual representation calls for an
|
|
immediate exploration with examples. We delay this step for a moment,
|
|
however, and instead define a function that checks whether a point is
|
|
inside some shape: <a name="(idx._(gentag._470))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Doing so is straightforward because of the given interpretation. It also
|
|
turns out that it is simpler than creating examples, and, surprisingly, the
|
|
function is helpful for formulating data examples.</div></p><p>Stop! Explain how and why <span class="RktSym">inside?</span> works.</p><p><div class="SIntrapara">Now let’s return to the problem of elements of <a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a>. Here is a
|
|
simplistic element of the class:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As required, it consumes a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> <span class="RktSym">p</span>, and its body compares the
|
|
coordinates of <span class="RktSym">p</span> to those of the point <span style="font-style: italic"></span>(<span style="font-style: italic"></span>3<span style="font-style: italic">,</span>4<span style="font-style: italic"></span>)<span style="font-style: italic"></span>,
|
|
meaning this function represents a single point. While the data
|
|
representation of a point as a <a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a> might seem silly, it suggests
|
|
how we can define functions that create elements of <a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a>: <a name="(idx._(gentag._471))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-point</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="hspace"> </span><span class="refelem"><span class="refcolumn"><span class="refcontent">We use “mk” because this function is not an ordinary constructor.</span></span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">y</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">a-sample-shape</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-point</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop again! Convince yourself that the last line creates a data
|
|
representation of <span style="font-style: italic"></span>(<span style="font-style: italic"></span>3<span style="font-style: italic">,</span>4<span style="font-style: italic"></span>)<span style="font-style: italic"></span>. Consider using DrRacket’s stepper.</div></p><p><div class="SIntrapara">If we were to <span style="font-weight: bold">design</span> such a function, we would formulate a purpose
|
|
statement and provide some illustrative examples. For the purpose we could
|
|
go with the obvious:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a representation for a point at (</span><span class="RktSym">x</span><span class="RktCmt">,</span><span class="RktSym">y</span><span class="RktCmt">)</span></p></blockquote></div><div class="SIntrapara">or, more concisely and more appropriately,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">represents a point at (</span><span class="RktSym">x</span><span class="RktCmt">,</span><span class="RktSym">y</span><span class="RktCmt">)</span></p></blockquote></div><div class="SIntrapara">For the examples we want to go with the interpretation of <a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a>. To
|
|
illustrate, <span class="RktPn">(</span><span class="RktSym">mk-point</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span> is supposed to evaluate
|
|
to a function that returns <span class="RktVal">#true</span> if, and only if, it is given
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>. Using <span class="RktSym">inside?</span>, we can express this
|
|
statement via tests:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-point</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-point</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In short, to make a point representation, we define a constructor-like
|
|
function that consumes the point’s two coordinates. Instead of a record,
|
|
this function uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> to construct another function. The
|
|
function that it creates consumes a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and determines whether its
|
|
<span class="RktSym">x</span> and <span class="RktSym">y</span> fields are equal to the originally given
|
|
coordinates.</div></p><p><div class="SIntrapara">Next we generalize this idea from simple points to shapes, say
|
|
circles. In your geometry courses, you learn that a circle
|
|
is a collection of points that all have the same distance to the center of
|
|
the circle—<wbr></wbr>the radius. For points inside the circle, the distance is
|
|
smaller than or equal to the radius. Hence, a function that creates a
|
|
<a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a> representation of a circle must consume three pieces: the two
|
|
coordinates for its center and the radius:<a name="(idx._(gentag._472))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a representation for a circle of radius </span><span class="RktSym">r</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">located at (</span><span class="RktSym">center-x</span><span class="RktCmt">, </span><span class="RktSym">center-y</span><span class="RktCmt">) </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktSym">center-x</span><span class="hspace"> </span><span class="RktSym">center-y</span><span class="hspace"> </span><span class="RktSym">r</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like <span class="RktSym">mk-point</span>, it produces a function via a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. The function that is returned determines whether some
|
|
given <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> is inside the circle. Here are some examples, again
|
|
formulated as tests:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">9</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The origin, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span>, is exactly five steps away from
|
|
<span style="font-style: italic"></span>(<span style="font-style: italic"></span>3<span style="font-style: italic">,</span>4<span style="font-style: italic"></span>)<span style="font-style: italic"></span>, the center of the circle; see <a href="part_one.html#%28part._sec~3astructures%29" data-pltdoc="x">Defining Structure Types</a>. Stop!
|
|
Explain the remaining examples.</div></p><p><a name="(counter._(exercise._ex~3adraw-shape1))"></a><span style="font-weight: bold">Exercise</span> 296. Use compass-and-pencil drawings to check the tests. <a href="part_three.html#%28counter._%28exercise._ex~3adraw-shape1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Mathematically, we say that a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> <span class="RktSym">p</span> is inside a circle if
|
|
the distance between <span class="RktSym">p</span> and the circle’s center is smaller than
|
|
the radius <span class="RktSym">r</span>. Let’s wish for the right kind of helper function
|
|
and write down what we have. <a name="(idx._(gentag._473))"></a>
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktSym">center-x</span><span class="hspace"> </span><span class="RktSym">center-y</span><span class="hspace"> </span><span class="RktSym">r</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">[</span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">distance-between</span><span class="hspace"> </span><span class="RktSym">center-x</span><span class="hspace"> </span><span class="RktSym">center-y</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">r</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <span class="RktSym">distance-between</span> function is a straightforward exercise.</div></p><p><a name="(counter._(exercise._ex~3ashape-distance))"></a><span style="font-weight: bold">Exercise</span> 297. Design the function <span class="RktSym">distance-between</span>.
|
|
It consumes two numbers and a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>: <span class="RktSym">x</span>, <span class="RktSym">y</span>, and
|
|
<span class="RktSym">p</span>. The function computes the distance between the points
|
|
(<span class="RktSym">x</span>, <span class="RktSym">y</span>) and <span class="RktSym">p</span>.</p><p><div class="SIntrapara"><span style="font-weight: bold">Domain Knowledge</span> The distance between <img src="pict_125.png" alt="image" width="38" height="12"/> and
|
|
<img src="pict_126.png" alt="image" width="38" height="12"/> is
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_127.png" alt="image" width="136" height="15"/></p></blockquote></div><div class="SIntrapara">that is, the distance of <img src="pict_128.png" alt="image" width="93" height="12"/> to the origin. <a href="part_three.html#%28counter._%28exercise._ex~3ashape-distance%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">The data representation of a rectangle is expressed in a similar manner: <a name="(idx._(gentag._474))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">represents a </span><span class="RktSym">width</span><span class="RktCmt"> by </span><span class="RktSym">height</span><span class="RktCmt"> rectangle whose </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">upper-left corner is located at (</span><span class="RktSym">ul-x</span><span class="RktCmt">, </span><span class="RktSym">ul-y</span><span class="RktCmt">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-rect</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-rect</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Stop! Formulate a negative test case.</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-rect</span><span class="hspace"> </span><span class="RktSym">ul-x</span><span class="hspace"> </span><span class="RktSym">ul-y</span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktSym">height</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktSym">ul-x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">ul-x</span><span class="hspace"> </span><span class="RktSym">width</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x"><=</a></span><span class="hspace"> </span><span class="RktSym">ul-y</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">ul-y</span><span class="hspace"> </span><span class="RktSym">height</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">Its constructor receives four numbers: the coordinates of the upper-left
|
|
corner, its width, and height. The result is again a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>
|
|
expression. As for circles, this function consumes
|
|
a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>, checking whether the <span class="RktSym">x</span>
|
|
and <span class="RktSym">y</span> fields of the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> are in the proper intervals.</div></p><p><div class="SIntrapara">At this point, we have only one task left, namely, the design of a function
|
|
that maps two <a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a> representations to their combination. The
|
|
signature and the header are easy: <a name="(idx._(gentag._475))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">combines two shapes into one </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-combination</span><span class="hspace"> </span><span class="RktSym">s1</span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Indeed, even the default value is straightforward. We know that a shape is
|
|
represented as a function from <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> to <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>, so we write
|
|
down a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> that consumes some <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and produces
|
|
<span class="RktVal">#false</span>, meaning it says no point is in the combination.</div></p><p><div class="SIntrapara">So suppose we wish to combine the circle and the rectangle from above:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">circle1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-circle</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">rectangle1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-rect</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">union1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-combination</span><span class="hspace"> </span><span class="RktSym">circle1</span><span class="hspace"> </span><span class="RktSym">rectangle1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Some points are inside and some outside of this combination:
|
|
</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://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">union1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">union1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">9</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">union1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> is inside both, there is no question that it
|
|
is inside the combination of the two. In a similar vein,
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">9</span><span class="RktPn">)</span> is in neither shape, and so it isn’t in the
|
|
combination. Finally, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span> is in <span class="RktSym">circle1</span> but
|
|
not in <span class="RktSym">rectangle1</span>. But the point must be in the combination of
|
|
the two shapes because every point that is in one or the other shape is in
|
|
their combination.</div></p><p><div class="SIntrapara">This analysis of examples implies a revision of <span class="RktSym">mk-combination</span>:
|
|
<a name="(idx._(gentag._476))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a><span class="RktCmt"> -> </span><a href="part_three.html#%28tech._shape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shape</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">mk-combination</span><span class="hspace"> </span><span class="RktSym">s1</span><span class="hspace"> </span><span class="RktSym">s2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">s1</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inside?</span><span class="hspace"> </span><span class="RktSym">s2</span><span class="hspace"> </span><span class="RktSym">p</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">The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span> expression says that the result is <span class="RktVal">#true</span> if one of
|
|
two expressions produces <span class="RktVal">#true</span>: <span class="RktPn">(</span><span class="RktSym">inside?</span><span class="stt"> </span><span class="RktSym">s1</span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> or
|
|
<span class="RktPn">(</span><span class="RktSym">inside?</span><span class="stt"> </span><span class="RktSym">s2</span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>. The first expression determines whether
|
|
<span class="RktSym">p</span> is in <span class="RktSym">s1</span> and the second one whether <span class="RktSym">p</span> is
|
|
in <span class="RktSym">s2</span>. And that is precisely a translation of our
|
|
above explanation into ISL+ .</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aanimate))"></a><span style="font-weight: bold">Exercise</span> 298. Design <span class="RktSym">my-animate</span>. Recall that the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._%28%28lib._2htdp%2Funiverse..rkt%29._animate%29%29" class="RktValLink" data-pltdoc="x">animate</a></span> function consumes the representation of a
|
|
<span style="font-style: italic">stream</span> of images, one per natural number. Since streams are
|
|
infinitely long, ordinary compound data cannot represent them. Instead, we
|
|
use functions:
|
|
</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">An </span><a name="(tech._imagestream)"></a><span style="font-style: italic">ImageStream</span><span class="RktCmt"> is a function: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">[</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> a stream </span><span class="RktSym">s</span><span class="RktCmt"> denotes a series of images</span></td></tr></table></blockquote></div><div class="SIntrapara">Here is a data example:<a name="(idx._(gentag._477))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_three.html#%28tech._imagestream%29" class="techoutside" data-pltdoc="x"><span class="techinside">ImageStream</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-rocket-scene</span><span class="hspace"> </span><span class="RktSym">height</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><img src="rocket.png" alt="" width="28" height="42"/><span class="hspace"> </span><span class="RktVal">50</span><span class="hspace"> </span><span class="RktSym">height</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace"> </span><span class="RktVal">60</span><span class="hspace"> </span><span class="RktVal">60</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You may recognize this as one of the first pieces of code in
|
|
the Prologue.</div></p><p>The job of <span class="RktPn">(</span><span class="RktSym">my-animate</span><span class="stt"> </span><span class="RktSym">s</span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span> is to show the images <span class="RktPn">(</span><span class="RktSym">s</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span>, <span class="RktPn">(</span><span class="RktSym">s</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span>, and so on at a rate of 30 images per second up to
|
|
<span class="RktSym">n</span> images total. Its result is the number of clock ticks passed
|
|
since launched.</p><p><span style="font-weight: bold">Note</span> This case is an example where it is possible to write down
|
|
examples/test cases easily, but these examples/tests per se do not inform
|
|
the design process of this <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span> function. Using functions as
|
|
data representations calls for more design concepts than this book supplies. <a href="part_three.html#%28counter._%28exercise._ex~3aanimate%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3ainfinite-set))"></a><span style="font-weight: bold">Exercise</span> 299. Design a data representation for finite and
|
|
infinite sets so that you can represent the sets of all odd numbers, all
|
|
even numbers, all numbers divisible by <span class="RktVal">10</span>, and so on.</p><p>Design the functions <span class="RktSym">add-element</span>, which adds an element to a set;
|
|
<span class="RktSym">union</span>, which combines the elements of two sets; and
|
|
<span class="RktSym">intersect</span>, which collects all elements common to two sets.</p><p><span style="font-weight: bold">Hint</span> Mathematicians deal with sets as functions that consume a
|
|
potential element <span class="RktSym">ed</span> and produce <span class="RktVal">#true</span> only if
|
|
<span class="RktSym">ed</span> belongs to the set. <a href="part_three.html#%28counter._%28exercise._ex~3ainfinite-set%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>18<tt> </tt><a name="(part._ch~3asummary3)"></a>Summary</h3><p>This third part of the book is about the role of abstraction in program
|
|
design. Abstraction has two sides: creation and use. It is therefore
|
|
natural if we summarize the chapter as two lessons:</p><p><div class="SIntrapara"><ol><li><p><span style="font-weight: bold">Repeated code patterns call for abstraction</span>. To abstract means
|
|
to factor out the repeated pieces of code—<wbr></wbr>the abstraction—<wbr></wbr>and to
|
|
parameterize over the differences. With the design of proper abstractions,
|
|
programmers save themselves future work and headaches because mistakes,
|
|
inefficiencies, and other problems are all in one place. One fix to the
|
|
abstraction thus eliminates any specific problem once and for all. In
|
|
contrast, the duplication of code means that a programmer must find all
|
|
copies and fix all of them when a problem is found.</p></li><li><p>Most languages come with a large collection of abstractions. Some are
|
|
contributions by the language design team; others are added by programmers
|
|
who use the language. To enable <span style="font-weight: bold">effective reuse of these
|
|
abstractions</span>, their creators must supply the appropriate pieces of
|
|
documentation—<wbr></wbr><span style="font-weight: bold">a purpose statement, a signature, and good
|
|
examples</span>—<wbr></wbr>and programmers use them to apply abstractions. </p></li></ol></div><div class="SIntrapara">All programming languages come with the means to build abstractions though
|
|
some means are better than others. All programmers must get to know the
|
|
means of abstraction and the abstractions that a language provides.
|
|
A discerning programmer will learn to distinguish programming languages
|
|
along these axes.</div></p><p><div class="SIntrapara">Beyond abstraction, this third part also introduces the idea that
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">functions are values, and they can represent information.</span></p></blockquote></div><div class="SIntrapara">While the idea is ancient for the Lisp family of programming languages
|
|
(such as ISL+) and for specialists in programming language research, it
|
|
has only recently gained acceptance in most modern mainstream
|
|
languages—<wbr></wbr>C#, C++, Java, JavaScript, Perl, Python.</div></p><div class="navsetbottom"><span class="navleft"><div class="nosearchform"></div> <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="i2-3.html" title="backward to "Intermezzo 2: Quote, Unquote"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "How to Design Programs, Second Edition"" data-pltdoc="x">up</a> <a href="i3-4.html" title="forward to "Intermezzo 3: Scope and Abstraction"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html> |