342 lines
253 KiB
HTML
342 lines
253 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>Intermezzo 3: Scope and 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="tocviewlink" data-pltdoc="x">Abstraction</a></td></tr><tr><td align="right"></td><td><a href="i3-4.html" class="tocviewselflink" 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></td><td><a href="i3-4.html" class="tocviewselflink" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right"></td><td><a href="i3-4.html#%28part._.Scope%29" class="tocviewlink" data-pltdoc="x">Scope</a></td></tr><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._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> in an informal manner, the introduction of such
|
||
|
abstraction mechanisms really requires additional terminology to
|
||
|
facilitate such discussions. In particular, these discussions need words
|
||
|
to delineate regions within programs and to refer to specific uses of
|
||
|
variables.</p><p>This intermezzo starts with a section that defines the new terminology:
|
||
|
scope, binding variables, and bound variables. It immediately uses this
|
||
|
new capability to introduce two abstraction mechanisms often found in
|
||
|
programming languages: <span class="stt">for</span> loops and pattern matching. The former is
|
||
|
an alternative to functions 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._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._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</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._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span>, and the like; the latter abstracts over the conditional in the
|
||
|
functions of the first three parts of the book. Both require not only the
|
||
|
definition of functions but also the creation of entirely new language
|
||
|
constructs, meaning they are not something programmers can usually design
|
||
|
and add to their vocabulary.</p><h3><a name="(part._.Scope)"></a>Scope</h3><p><div class="SIntrapara">Consider the following two definitions:
|
||
|
</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="highlighted"><span class="RktSym">x</span></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="highlighted"><span class="RktSym">x</span></span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">x</span></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">25</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">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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</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"><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">1</span><span class="RktPn">)</span><span class="RktPn">)</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"><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="RktSym">x</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></td></tr></table></blockquote></div><div class="SIntrapara">Clearly, the occurrences of <span class="RktSym">x</span> in <span class="RktSym">f</span> are completely
|
||
|
unrelated to the occurrences of <span class="RktSym">x</span> in the definition of
|
||
|
<span class="RktSym">g</span>. We could systematically replace the shaded occurrences
|
||
|
with <span class="RktSym">y</span> and the function would still compute the exact same
|
||
|
result. In short, the shaded occurrences of <span class="RktSym">x</span> have meaning
|
||
|
only inside the definition of <span class="RktSym">f</span> and nowhere else.</div></p><p>At the same time, the first occurrence of <span class="RktSym">x</span> in <span class="RktSym">f</span> is
|
||
|
different from the others. When we evaluate <span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span>, the occurrence
|
||
|
of <span class="RktSym">f</span> completely disappears while those of <span class="RktSym">x</span> are replaced
|
||
|
with <span class="RktSym">n</span>. To distinguish these two kinds of variable occurrences,
|
||
|
we call the <span class="RktSym">x</span> in the function header a <span style="font-style: italic">binding
|
||
|
occurrence</span> and those in the function’s body the <span style="font-style: italic">bound
|
||
|
occurrences</span>. We also say that the binding occurrence of <span class="RktSym">x</span> binds
|
||
|
all occurrences of <span class="RktSym">x</span> in the body of <span class="RktSym">f</span>. Indeed, people
|
||
|
who study programming languages even have a name for the region where a
|
||
|
binding occurrence works, namely, its <span style="font-style: italic">lexical scope</span>.</p><p>The definitions of <span class="RktSym">f</span> and <span class="RktSym">g</span> bind two more names:
|
||
|
<span class="RktSym">f</span> and <span class="RktSym">g</span>. Their scope is called <span style="font-style: italic">top-level scope</span>
|
||
|
because we think of scopes as nested (see below).</p><p><div class="SIntrapara">The term <span style="font-style: italic">free occurrence</span> applies to a variable without any
|
||
|
binding occurrence. It is a name without definition, that is, neither the
|
||
|
language nor its teachpacks nor the program associates it with some value.
|
||
|
For example, if you were to put the above program into a definitions area
|
||
|
by itself and run it, entering <span class="RktSym">f</span>, <span class="RktSym">g</span>, and <span class="RktSym">x</span> at
|
||
|
the prompt of the interactions would show that the first two are defined
|
||
|
and the last one is not:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktSym">f</span></td></tr><tr><td><p><span class="RktRes">f</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktSym">g</span></td></tr><tr><td><p><span class="RktRes">g</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktSym">x</span></td></tr><tr><td><p><span class="RktErr">x:this variable is not defined</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The description of lexical scope suggests a pictorial
|
||
|
representation of <span class="RktSym">f</span>’s definition:<span class="refelem"><span class="refcolumn"><span class="refcontent">DrRacket’s
|
||
|
“Check Syntax” functionality draws diagrams like these.</span></span></span>
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_129.png" alt="image" width="164.42578125" height="52.0"/></p></blockquote></div><div class="SIntrapara">Here is an arrow diagram for top-level scope:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_130.png" alt="image" width="222.03515625" height="132.0"/></p></blockquote></div><div class="SIntrapara">Note that the scope of <span class="RktSym">f</span> includes all definitions above and
|
||
|
below its definition. The bullet over the first occurrence indicates that
|
||
|
it is a binding occurrence. The arrows from the binding occurrence to the
|
||
|
bound occurrences suggest the flow of values. When the value of a binding
|
||
|
occurrence becomes known, the bound occurrences receive their values from
|
||
|
there.</div></p><p><div class="SIntrapara">Along similar lines, these diagrams also explain how renaming works. If you
|
||
|
wish to rename a function parameter, you search for all bound occurrences
|
||
|
in scope and replace them. For example, renaming <span class="RktSym">f</span>’s <span class="RktSym">x</span>
|
||
|
to <span class="RktSym">y</span> in the program above means that
|
||
|
</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="RktPn">(</span><span class="RktSym"><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="RktSym">x</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">25</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">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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</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"><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">1</span><span class="RktPn">)</span><span class="RktPn">)</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"><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="RktSym">x</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></td></tr></table></blockquote></div><div class="SIntrapara">changes only two occurrences of <span class="RktSym">x</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">f</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="RktPn">(</span><span class="RktSym"><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="hspace"> </span><span class="RktVal">25</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">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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</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"><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">1</span><span class="RktPn">)</span><span class="RktPn">)</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"><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="RktSym">x</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></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3ascope1))"></a><span style="font-weight: bold">Exercise</span> 300. Here is a simple ISL+ program:
|
||
|
</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">p1</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://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="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="RktPn">(</span><span class="RktSym"><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">2</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._%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">2</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">22</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="RktPn">(</span><span class="RktSym">p2</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._%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.r
|
||
|
occurrences. Draw arrows from <span class="RktSym">p1</span> to all bound occurrences of
|
||
|
<span class="RktSym">p1</span>. Check the results with DrRacket’s <span class="emph">CHECK SYNTAX</span>
|
||
|
functionality. <a href="i3-4.html#%28counter._%28exercise._ex~3ascope1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">In contrast to top-level function definitions, the scope of 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> is limited. Specifically, the scope of local
|
||
|
definitions <span class="emph">is</span> 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. Consider the
|
||
|
definition of an auxiliary function <span class="RktSym">f</span> 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. It binds all occurrences 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
|
||
|
but none that occurs outside:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_131.png" alt="image" width="373.259765625" height="164.0"/></p></blockquote></div><div class="SIntrapara">The two occurrences outside 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> are not bound by the local
|
||
|
definition of <span class="RktSym">f</span>. As always, the parameters of a function
|
||
|
definition, local or not, are only bound in the function’s body.</div></p><p><div class="SIntrapara">Since the scope of a function name or a function parameter is a textual
|
||
|
region, people also draw box diagrams to indicate scope. More precisely,
|
||
|
for parameters a box is drawn around the body of a function:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_132.png" alt="image" width="137.419921875" height="47.603515625"/></p></blockquote></div><div class="SIntrapara">In the case 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>, the box is drawn around the entire
|
||
|
expression:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_133.png" alt="image" width="317.44921875" height="79.603515625"/></p></blockquote></div><div class="SIntrapara">In this example, the box describes the scope of the definitions
|
||
|
of <span class="RktSym">f</span> and <span class="RktSym">g</span>.</div></p><p><div class="SIntrapara">Drawing a box around a scope, we can also easily understand what it means
|
||
|
to reuse the name of a function inside 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:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_134.png" alt="image" width="391.259765625" height="155.20703125"/></p></blockquote></div><div class="SIntrapara">The gray box describes the scope of the inner definition of <span class="RktSym">f</span>;
|
||
|
the white box is the scope of the outer definition of <span class="RktSym">f</span>.
|
||
|
Accordingly, all occurrences of <span class="RktSym">f</span> in the gray box refer to the
|
||
|
inner <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>; all those in the white box, minus the gray one,
|
||
|
refer to the definition in the outer <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 other words, the
|
||
|
gray box is a <span style="font-style: italic">hole</span> in the scope of the outer definition of
|
||
|
<span class="RktSym">f</span>.</div></p><p><div class="SIntrapara">Holes can also occur in the scope of a parameter definition:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_135.png" alt="image" width="225.6328125" height="91.20703125"/></p></blockquote></div><div class="SIntrapara">In this function, the parameter <span class="RktSym">x</span> is used twice: for <span class="RktSym">f</span>
|
||
|
and <span class="RktSym">g</span>; the scope of the latter is thus a hole in the scope of the
|
||
|
former.</div></p><p>In general, if the same name occurs more than once in a function, the boxes
|
||
|
that describe the corresponding scopes never overlap. In some cases the
|
||
|
boxes are nested within each other, which gives rise to holes. Still, the
|
||
|
picture is always that of a hierarchy of smaller and smaller nested boxes.</p><p><div class="SIntrapara"><a name="(idx._(gentag._478))"></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="RktPn">(</span><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">insertion-sort</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._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"><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">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">add</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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"><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.or
|
||
|
occurrence 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._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> and <span class="RktSym">alon</span> in
|
||
|
<a href="i3-4.html#%28counter._%28figure._fig~3aex~3ascope2%29%29" data-pltdoc="x">figure <span class="FigureRef">105</span></a>. Then draw arrows from each occurrence 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._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> to the appropriate binding occurrence. Now repeat the
|
||
|
exercise for the variant in <a href="i3-4.html#%28counter._%28figure._fig~3aex~3ascope2-2%29%29" data-pltdoc="x">figure <span class="FigureRef">106</span></a>.
|
||
|
Do the two functions differ other than in name? <a href="i3-4.html#%28counter._%28exercise._ex~3ascope2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._479))"></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="RktPn">(</span><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">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._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"><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">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">add</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate
|
||
|
receives its value from its binding occurrence. Consider the following 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%29%29" class="RktStxLink" data-pltdoc="x">define</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">x</span></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Where is the shaded occurrence of <span class="RktSym">x</span> bound? Since the
|
||
|
definition is a constant definition and not a function definition, we need
|
||
|
to evaluate the right-hand side immediately. What should be the value of
|
||
|
the right-hand side according to our rules? <a href="i3-4.html#%28counter._%28exercise._ex~3ascope-meaning%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">As discussed in <a href="part_three.html#%28part._sec~3aint-lambda%29" data-pltdoc="x">Functions from <span class="RktSym"><span class="RktStxLink">lambda</span></span></a>, 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 is just a
|
||
|
short-hand 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. That is, if
|
||
|
<span class="RktSym">a-new-name</span> does not occur in <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span>,
|
||
|
</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-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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">is short for
|
||
|
</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">a-new-name</span><span class="hspace"> </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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">a-new-name</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The short-hand explanation suggests that
|
||
|
</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-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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">introduces <span class="RktSym">x-1</span>, ..., <span class="RktSym">x-n</span> as binding occurrences and that the scope
|
||
|
of parameters 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._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span>, for example:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_136.png" alt="image" width="186.029296875" height="68.0"/></p></blockquote></div><div class="SIntrapara">Of course, if <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._exp%29%29" class="RktValLink" data-pltdoc="x">exp</a></span> contains further binding constructs (say, a
|
||
|
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._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> expression), then the scope of the variables may
|
||
|
have a hole.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alambda2))"></a><span style="font-weight: bold">Exercise</span> 303. Draw arrows from the shaded occurrences of
|
||
|
<span class="RktSym">x</span> to their binding occurrences in each of the following three
|
||
|
<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><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="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="highlighted"><span class="RktSym">x</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._%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></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="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="highlighted"><span class="RktSym">x</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._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">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">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..
|
||
|
scope as necessary. <a href="i3-4.html#%28counter._%28exercise._ex~3alambda2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h3><a name="(part._.I.S.L_for_.Loops)"></a>ISL for Loops</h3><p><div class="SIntrapara">Even though it never mentions the word, <a href="part_three.html" data-pltdoc="x">Abstraction</a> introduces
|
||
|
loops. Abstractly, a <span style="font-style: italic">loop</span> traverses compound data,
|
||
|
processing</div><div class="SIntrapara"><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktSym">2htdp/abstraction</span><span class="RktPn">)</span> to the <span style="font-weight: bold">definitions
|
||
|
area</span>, or select <span class="stt">Add Teachpack</span> from the <span class="stt">Language</span> menu and
|
||
|
choose <span class="stt">abstraction</span> from the <span class="stt">Preinstalled HtDP/2e Teachpack</span> menu.</p></blockquote></blockquote></blockquote></div><div class="SIntrapara">one piece at a
|
||
|
time. In the process, loops also synthesize data. For example,
|
||
|
<span class="RktSym"><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> traverses a list, applies a function to each item, and
|
||
|
collects the results in a list. Similarly, <span class="RktSym"><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> enumerates
|
||
|
the sequence of predecessors of a natural number (from <span class="RktVal">0</span> to
|
||
|
<span class="RktPn">(</span><span class="RktSym"><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>), maps each of these to some value, and also gathers the
|
||
|
results in a list.</div></p><p>The loops of ISL+ differ from those in conventional languages in two
|
||
|
ways. First, a conventional loop does not directly create new data; in
|
||
|
contrast, abstractions 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._map%29%29" class="RktValLink" data-pltdoc="x">map</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._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span> are
|
||
|
all about computing new data from traversals. Second, conventional
|
||
|
languages often provide only a fixed number of loops; an ISL+
|
||
|
programmer defines new loops as needed. Put differently, conventional
|
||
|
languages view loops as syntactic constructs akin 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._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> or
|
||
|
<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>, and their introduction requires a detailed explanation of
|
||
|
their vocabulary, grammar, scope, and meaning.</p><p>Loops as syntactic constructs have two advantages over the functional loops
|
||
|
of the preceding part. On
|
||
|
the one hand, their shape tends to signal intentions more directly than a
|
||
|
composition of functions. On the other hand, language implementations
|
||
|
typically translate syntactic loops into faster commands for computers
|
||
|
than functional loops. It is therefore common that even functional
|
||
|
programming languages—<wbr></wbr>with all their emphasis on functions and function
|
||
|
compositions—<wbr></wbr>provide syntactic loops.</p><p>In this section, we introduce ISL+’s so-called <span class="stt">for</span>
|
||
|
loops. The goal is to illustrate how to think about conventional loops as
|
||
|
linguistic constructs and to indicate how programs built with abstractions
|
||
|
may use loops instead. <a href="i3-4.html#%28counter._%28figure._fig~3asyn-for-loops%29%29" data-pltdoc="x">Figure <span class="FigureRef">107</span></a> spells out the
|
||
|
grammar of our selected <span class="stt">for</span> loops as an extension of BSL’s grammar
|
||
|
from <a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a>. Every loop is an expression and, like all compound
|
||
|
constructs, is marked with a keyword. The latter is followed by a
|
||
|
parenthesized sequence of so-called <span style="font-style: italic">comprehension clauses</span> and a
|
||
|
single expression. The clauses introduce so-called <span style="font-style: italic">loop
|
||
|
variables</span>, and the expression at the end is the <span style="font-style: italic">loop body</span>.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><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="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">clause</span><span class="hspace"> </span><span class="RktVar">clause</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><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">clause</span><span class="hspace"> </span><span class="RktVar">clause</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><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fand%29%29" class="RktStxLink" data-pltdoc="x">for/and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">clause</span><span class="hspace"> </span><span class="RktVar">clause</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><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Fand%29%29" class="RktStxLink" data-pltdoc="x">for*/and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">clause</span><span class="hspace"> </span><span class="RktVar">clause</span><span class="hspace">
|
||
|
come in six pairs: a <span class="stt">for</span> and <span class="stt">for*</span> variant for each of <span class="stt">list</span>,
|
||
|
<span class="stt">and</span>, <span class="stt">or</span>, <span class="stt">sum</span>, <span class="stt">product</span>, and
|
||
|
<span class="stt">string</span>.<span class="refelem"><span class="refcolumn"><span class="refcontent">Racket’s version of these loops comes with more
|
||
|
functionality than those presented here, and the language has many more
|
||
|
loops than this.</span></span></span> All <span class="stt">for</span> loops bind the variables of their clauses
|
||
|
in the body; the <span class="stt">for*</span> variants also bind variables in the subsequent
|
||
|
clauses. The following two near-identical code snippets illustrate the
|
||
|
difference between these two scoping rules:
|
||
|
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span></p></td><td><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_137.png" alt="image" width="193.23046875" height="116.0"/></p></td><td><p><span class="hspace"> </span></p></td><td><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_138.png" alt="image" width="200.431640625" height="116.0"/></p></td></tr></table></blockquote></div><div class="SIntrapara">The syntactic difference is that the left one uses <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> and
|
||
|
the right one <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span>. In terms of scope, the two strongly
|
||
|
differ as the arrows indicate. While both pieces introduce the loop
|
||
|
variables <span class="RktSym">width</span> and <span class="RktSym">height</span>, the left one uses an
|
||
|
externally defined variable for <span class="RktSym">height</span>’s initial value and the
|
||
|
right one uses the first loop variable.</div></p><p><div class="SIntrapara">Semantically, a <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> expression evaluates the
|
||
|
expressions in its clauses to generate sequences of values. If a clause
|
||
|
expression evaluates to
|
||
|
</div><div class="SIntrapara"><ul><li><p>a list, its items make up the sequence values;</p></li><li><p>a natural number <span class="RktSym">n</span>, the sequence consists of <span class="RktVal">0</span>,
|
||
|
<span class="RktVal">1</span>, ..., <span class="RktPn">(</span><span class="RktSym"><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>; and</p></li><li><p>a string, its one-character strings are the sequence items.</p></li></ul></div><div class="SIntrapara">Next, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> evaluates the loop body with the loop variables
|
||
|
successively bound to the values of the generated sequence(s).
|
||
|
Finally, it collects the values of its body into a list.
|
||
|
The evaluation of a <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> expression stops when the shortest
|
||
|
sequence is exhausted.</div></p><p><span style="font-weight: bold">Terminology</span> Each evaluation of a loop body is called an
|
||
|
<span style="font-style: italic">iteration</span>. Similarly, a loop is said to <span style="font-style: italic">iterate</span> over
|
||
|
the values of its loop variables.</p><p><div class="SIntrapara">Based on this explanation, we can easily generate the list from <span class="RktVal">0</span> to <span class="RktVal">9</span>:
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list 0 1 2 3 4 5 6 7 8 9)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">This is the equivalent of 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._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span> loop:
|
||
|
</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">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#%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">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 0 1 2 3 4 5 6 7 8 9)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The second example “zips” together two sequences:
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">j</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="RktVal">)</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="RktSym">i</span><span class="hspace"> </span><span class="RktSym">j</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (list 0 'a) (list 1 'b))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">For comparison again, here is the same expression using plain ISL+:
|
||
|
</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#%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-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._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</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#%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">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</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#%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">j-s</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="RktVal">)</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._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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">i-s</span><span class="hspace"> </span><span class="RktSym">j-s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (list 0 'a) (list 1 'b))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The final example emphasizes designing with <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span>:
|
||
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design <span class="RktSym">enumerate</span>. The function consumes a list
|
||
|
and produces a list of the same items paired with their relative index.</p></blockquote></div><div class="SIntrapara">Stop! Design this function systematically, using ISL+’s abstractions.</div></p><p><div class="SIntrapara">With <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span>, this problem has a straightforward solution: <a name="(idx._(gentag._480))"></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"> 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"> [</span><a href="part_three.html#%28tech._sim-dd._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">List</span></a><span class="RktCmt"> N X]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">pairs each item in </span><span class="RktSym">lx</span><span class="RktCmt"> with its index </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">enumerate</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="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">a</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">b</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">c</span><span class="RktVal">)</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">enumerate</span><span class="hspace"> </span><span class="RktSym">lx</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/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">ith</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace"> </span><span class="RktSym">lx</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="RktP
|
||
|
and a list of numbers from <span class="RktVal">0</span> to <span class="RktPn">(</span><span class="RktSym">length</span><span class="stt"> </span><span class="RktSym">lx</span><span class="RktPn">)</span> (minus
|
||
|
<span class="RktVal">1</span>); the loop body combines the index (plus <span class="RktVal">1</span>) with the
|
||
|
list item.</div></p><p><div class="SIntrapara">In semantic terms, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> iterates over the sequences in a
|
||
|
nested fashion while <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> traverses them in parallel. That
|
||
|
is, a <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> expression basically unfolds into a nest of
|
||
|
loops:
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">j</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="RktVal">)</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></td></tr></table></blockquote></div><div class="SIntrapara">is short for
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">2</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/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">j</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="RktVal">)</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></td></tr></table></blockquote></div><div class="SIntrapara">In addition, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> collects the nested lists into a
|
||
|
<span style="font-weight: bold">single</span> list by concatenating them 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> 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._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span>.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afor-star0))"></a><span style="font-weight: bold">Exercise</span> 304. Evaluate
|
||
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">j</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="RktVal">)</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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktSym">j</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">and
|
||
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">j</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="RktVal">)</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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktSym">j</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">in the interactions area of DrRacket. <a href="i3-4.html#%28counter._%28exercise._ex~3afor-star0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">Let’s continue the exploration by turning the difference in scoping between
|
||
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> into a semantic difference:
|
||
|
</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#%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">2</span><span class="RktPn">)</span></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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">]</span><span class="RktPn">[</span><span class="RktSym">height</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="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">width</span><span class="hspace"> </span><span class="RktSym">height</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (list 0 0) (list 1 1))</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">]</span><span class="RktPn">[</span><span class="RktSym">height</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="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">width</span><span class="hspace"> </span><span class="RktSym">height</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (list 1 0) (list 2 0) (list 2 1))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">To understand the first interaction, remember that <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span>
|
||
|
traverses the two sequences in parallel and stops when the shorter one is
|
||
|
exhausted. Here, the two sequences are
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0"><tr><td align="left"><p><span style="font-style: italic">width</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>0<span style="font-style: italic">, </span>1<span style="font-style: italic">, </span>2<span style="font-style: italic"></span></p></td></tr><tr><td align="left"><p><span style="font-style: italic">height</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>0<span style="font-style: italic">, </span>1<span style="font-style: italic"></span></p></td></tr><tr><td align="left"><p><span style="font-style: italic">body</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">0</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._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</span><span class="RktPn">)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The first two rows show the values of the two loop variables, which change
|
||
|
in tandem. The last row shows the result of each iteration, which explains the first
|
||
|
result and the absence of a pair containing <span class="RktVal">2</span>.</div></p><p><div class="SIntrapara">Now contrast this situation with <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span>:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0"><tr><td align="left"><p><span style="font-style: italic">width</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>0<span style="font-style: italic"></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>1<span style="font-style: italic"></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>2<span style="font-style: italic"></span></p></td></tr><tr><td align="left"><p><span style="font-style: italic">height</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>0<span style="font-style: italic"></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic"></span>0<span style="font-style: italic">, </span>1<span style="font-style: italic"></span></p></td></tr><tr><td align="left"><p><span style="font-style: italic">body</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p><span style="font-style: italic">=</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><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._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">0</span><span class="RktPn">)</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><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._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">0</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._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="RktPn">)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">While the first row is like the one for <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span>, the second one now
|
||
|
displays sequences of numbers in its cells. The implicit nesting of
|
||
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> means that each iteration recomputes <span class="RktSym">height</span>
|
||
|
for a specific value of <span class="RktSym">width</span> and thus creates a distinct
|
||
|
<span style="font-weight: bold">sequence</span> of <span class="RktSym">height</span> values. This explains why the first cell
|
||
|
of <span class="RktSym">height</span> values is empty; after all, there are no natural numbers
|
||
|
between <span class="RktVal">0</span> (inclusive) and <span class="RktVal">0</span> (exclusive). Finally, each
|
||
|
nested <span class="stt">for</span> loop yields a sequences of pairs, which are collected into
|
||
|
a single list of pairs.</div></p><p><div class="SIntrapara">Here is a problem that illustrates this use of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> in context:
|
||
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design <span class="RktSym">cross</span>. The function consumes two lists, <span class="RktSym">l1</span>
|
||
|
and <span class="RktSym">l2</span>, and produces pairs of all items from these lists.</p></blockquote></div><div class="SIntrapara">Stop! Take a moment to design the function, using existing abstractions.</div></p><p><div class="SIntrapara">As you design <span class="RktSym">cross</span>, you work through a table such as:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p><span class="RktSym">cross</span></p></td><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">a</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">b</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">c</span></p></td></tr><tr><td style="border-right: 1px solid black;"><p><span class="RktVal">1</span></p></td><td style="border-right: 1px solid black;"><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">c</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></p></td></tr><tr><td style="border-right: 1px solid black;"><p><span class="RktVal">2</span></p></td><td style="border-right: 1px solid black;"><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVa
|
||
|
Each cell in the table corresponds to one of the pairs to be generated.</div></p><p><div class="SIntrapara">Since the purpose of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> is an enumeration of all such pairs, defining <span class="RktSym">cross</span>
|
||
|
via <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> is straightforward: <a name="(idx._(gentag._481))"></a> <a name="(idx._(gentag._482))"></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"> 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><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._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">List</span></a><span class="RktCmt"> X Y]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">generates all pairs of items from </span><span class="RktSym">l1</span><span class="RktCmt"> and </span><span class="RktSym">l2</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">cross</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="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="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._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">c</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">length</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">6</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">cross</span><span class="hspace"> </span><span class="RktSym">l1</span><span class="hspace"> </span><span class="RktSym">l2</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/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></s
|
||
|
we do not wish to predict the exact order in which <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span>
|
||
|
generates the pairs.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._483))"></a>
|
||
|
<a name="(idx._(gentag._484))"></a>
|
||
|
<a name="(idx._(gentag._485))"></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"> 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"> [</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">creates a list of all rearrangements of the items in </span><span class="RktSym">w</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">arrangements</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://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">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">item</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">arrangement-without-item</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._remove%29%29" class="RktValLink" data-pltdoc="x">remove</a></span><span class="hspace"> </span><span class="RktSym">i
|
||
|
of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span>. It displays a compact solution of the extended
|
||
|
design problem of creating all possible rearrangements of the letters in a
|
||
|
given list.</p><p>While <a href="part_two.html#%28part._sec~3apermute%29" data-pltdoc="x">Word Games, the Heart of the Problem</a> sketches the proper design of this complex program,
|
||
|
<a href="i3-4.html#%28counter._%28figure._fig~3apermutation-for%29%29" data-pltdoc="x">figure <span class="FigureRef">108</span></a> uses the combined power of
|
||
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2A%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for*/list</a></span> and an unusual form of recursion to define the same
|
||
|
<span class="refelem"><span class="refcolumn"><span class="refcontent">We thank Mark Engelberg for suggesting this exhibition of
|
||
|
expressive power.</span></span></span>
|
||
|
program as a single, five-line function definition. The figure merely
|
||
|
exhibits the power of these abstractions; for the underlying design, see
|
||
|
especially <a href="part_five.html#%28counter._fsm._%28exercise._ex~3apermutation-gen%29%29" data-pltdoc="x">exercise 477</a>. <span style="font-weight: bold">End</span></p><p><div class="SIntrapara">The <span class="stt">.../list</span> suffix clearly signals that the loop expression creates a
|
||
|
list. In addition, the teachpack comes with <span class="stt">for</span> and <span class="stt">for*</span> loops that
|
||
|
have equally suggestive suffixes:
|
||
|
</div><div class="SIntrapara"><ul><li><p><span class="stt">.../and</span> collects the values of all iterations 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._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span>:</p><p><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fand%29%29" class="RktStxLink" data-pltdoc="x">for/and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">10</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._~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._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fand%29%29" class="RktStxLink" data-pltdoc="x">for/and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">10</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._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~3d%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">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">9</span></p></td></tr></table></blockquote></div><div class="SIntrapara">For pragmatics, the loop returns the last generated value or <span class="RktVal">#false</span>.</div></p></li><li><p><div class="SIntrapara"><span class="stt">.../or</span> is like <span class="stt">.../and</span> but 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._or%29%29" class="RktStxLink" data-pltdoc="x">or</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-lam
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2For%29%29" class="RktStxLink" data-pltdoc="x">for/or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">10</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._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._~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._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">9</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2For%29%29" class="RktStxLink" data-pltdoc="x">for/or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">10</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._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="RktSym">i</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr></table></blockquote></div><div class="SIntrapara">These loops return the first value that is not <span class="RktVal">#false</span>.</div></p></li><li><p><div class="SIntrapara"><span class="stt">.../sum</span> adds up the numbers that the iterations generate:
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fsum%29%29" class="RktStxLink" data-pltdoc="x">for/sum</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktVal">"abc"</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._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">294</span></p></td></tr></table></blockquote></div></p></li><li><p><div class="SIntrapara"><span class="stt">.../product</span> multiplies the numbers that the iterations generate
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fproduct%29%29" class="RktStxLink" data-pltdoc="x">for/product</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktVal">"abc"</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._%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._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">970200</span></p></td></tr></table></blockquote></div></p></li><li><p><div class="SIntrapara"><span class="stt">.../string</span> creates <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s from the <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a> sequence:
|
||
|
</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#%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</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fstring%29%29" class="RktStxLink" data-pltdoc="x">for/string</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">j</span><span class="hspace"> </span><span class="RktVal">10</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._int-~3estring%29%29" class="RktValLink" data-pltdoc="x">int->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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">j</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"abcdefghij"</span></p></td></tr></table></blockquote></div></p></li></ul></div><div class="SIntrapara">Stop! Imagine how a <span class="RktSym">for/fold</span> loop would work.</div></p><p>Stop again! It is an instructive exercise to reformulate all of the above
|
||
|
examples using the existing abstractions in ISL+. Doing so also
|
||
|
indicates how to design functions with <span class="stt">for</span> loops instead of abstract functions.
|
||
|
<span style="font-weight: bold">Hint</span> Design <span class="RktSym">and-map</span> and <span class="RktSym">or-map</span>, which work 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._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>, respectively, but which return the
|
||
|
appropriate non-<span class="RktVal">#false</span> values.</p><p><div class="SIntrapara"><a name="(idx._(gentag._486))"></a>
|
||
|
<a name="(idx._(gentag._487))"></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._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> </span><span class="RktSym">sequence?</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">constructs the </span><span style="font-weight: bold">infinite</span><span class="RktCmt"> sequence of natural numbers, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">starting from </span><span class="RktSym">n</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/teachpack/2htdpabstraction.html#%28def._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._in-naturals%29%29" class="RktValLink" data-pltdoc="x">in-naturals</a></span><span class="hspace"> </span><span class="RktSym">n</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><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"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> </span><span class="RktSym">sequence?</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">constructs the following </span><span style="font-weight: bold">finite</span><span class="RktCmt"> sequence of natural numbers:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktSym">start</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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktSym">start</span><span class="stt"> </span><span class="RktSym">step</span><span class="RktPn">)</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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktSym">start</span><span class="stt"> </span><span class="RktSym">step</span><span class="stt"> </span><span class="RktSym">step</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">...</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"
|
||
|
through <span class="RktPn">(</span><span class="RktSym"><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>. Often programs need to step through
|
||
|
nonsequential sequences of numbers; other times, an unlimited supply of
|
||
|
numbers is needed. To accommodate this form of programming, Racket comes
|
||
|
with functions that generate sequences, and <a href="i3-4.html#%28counter._%28figure._fig~3asequence-makers%29%29" data-pltdoc="x">figure <span class="FigureRef">109</span></a>
|
||
|
lists two that are provided in the abstraction teachpack for ISL+.</p><p><div class="SIntrapara">With the first one, we can simplify the <span class="RktSym">enumerate</span> function a bit:<a name="(idx._(gentag._488))"></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">enumerate.v2</span><span class="hspace"> </span><span class="RktSym">lx</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/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Flist%29%29" class="RktStxLink" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">item</span><span class="hspace"> </span><span class="RktSym">lx</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">ith</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28def._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._in-naturals%29%29" class="RktValLink" data-pltdoc="x">in-naturals</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">ith</span><span class="hspace"> </span><span class="RktSym">item</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Here <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28def._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._in-naturals%29%29" class="RktValLink" data-pltdoc="x">in-naturals</a></span> is used to generate the infinite sequence of
|
||
|
natural numbers starting at <span class="RktVal">1</span>; the <span class="stt">for</span> loop stops when
|
||
|
<span class="RktSym">lx</span> is exhausted.</div></p><p><div class="SIntrapara">With the second one, it is, for example, possible to step through the even
|
||
|
numbers among the first <span class="RktSym">n</span>: <a name="(idx._(gentag._489))"></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._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</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">adds the even numbers between </span><span class="RktVal">0</span><span class="RktCmt"> and </span><span class="RktSym">n</span><span class="RktCmt"> (exclusive)</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">sum-evens</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</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">sum-evens</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</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">sum-evens</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._for%2Fsum%29%29" class="RktStxLink" data-pltdoc="x">for/sum</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">i</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28def._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._in-range%29%29" class="RktValLink" data-pltdoc="x">in-range</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">i</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Although this use may appear trivial, many problems originating in
|
||
|
mathematics call for just such loops, which is precisely why concepts such
|
||
|
as <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28def._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._in-range%29%29" class="RktValLink" data-pltdoc="x">in-range</a></span> are found in many programming languages.</div></p><p><a name="(counter._(exercise._ex~3ause-map-for))"></a><span style="font-weight: bold">Exercise</span> 305. Use loops to define <span class="RktSym">convert-euro</span>. See
|
||
|
<a href="part_three.html#%28counter._%28exercise._ex~3ause-map%29%29" data-pltdoc="x">exercise 267</a>. <a href="i3-4.html#%28counter._%28exercise._ex~3ause-map-for%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3abuild-list1-for))"></a><span style="font-weight: bold">Exercise</span> 306. Use loops 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, use loops to 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>. <a href="i3-4.html#%28counter._%28exercise._ex~3abuild-list1-for%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3aand-or-map-loop))"></a><span style="font-weight: bold">Exercise</span> 307. Define <span class="RktSym">find-name</span>. The function
|
||
|
consumes a name and a list of names. It retrieves the first name
|
||
|
on the latter that is equal to, or an extension of, the former.</p><p>Define a function that ensures that no name on some list of names exceeds some
|
||
|
given width. Compare with <a href="part_three.html#%28counter._%28exercise._ex~3aand-or-map%29%29" data-pltdoc="x">exercise 271</a>. <a href="i3-4.html#%28counter._%28exercise._ex~3aand-or-map-loop%29%29" class="ex-end" data-pltdoc="x"></a></p><h3><a name="(part._.Pattern_.Matching)"></a>Pattern Matching</h3><p>When we design a function for a data definition with six clauses, we use a
|
||
|
six-pronged <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. When we formulate one 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._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses, we use a predicate to<span class="refelem"><span class="refcolumn"><span class="refcontent">The interested
|
||
|
instructor may wish to study the facilities of <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/abstraction</span></span> teachpack</span> to
|
||
|
define algebraic data types.</span></span></span> determine whether this clause
|
||
|
should process the given value and, if so, selectors to deconstruct any
|
||
|
compound values. The first three parts of this book explain this idea over
|
||
|
and over again.</p><p>Repetition calls for abstraction. While <a href="part_three.html" data-pltdoc="x">Abstraction</a> explains how
|
||
|
programmers can create some of these abstractions, the predicate-selector
|
||
|
pattern can be addressed only by a language designer. In particular, the
|
||
|
designers of functional programming languages have recognized the need for
|
||
|
abstracting these repetitive uses of predicates and selectors. These
|
||
|
languages therefore provide <span style="font-style: italic">pattern matching</span> as a linguistic
|
||
|
construct that combines and simplifies these <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> clauses.</p><p>This section presents a simplification of Racket’s pattern matcher.
|
||
|
<a href="i3-4.html#%28counter._%28figure._fig~3asyn-match%29%29" data-pltdoc="x">Figure <span class="FigureRef">110</span></a> displays its grammar; match is clearly a
|
||
|
syntactically complex construct. While its outline resembles that 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._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>, it features patterns instead of conditions, and they come
|
||
|
with their own rules.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><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="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktVar">expr</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">pattern</span><span class="hspace"> </span><span class="RktVar">expr</span><span class="RktPn">]</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">pattern</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="RktVar">variable</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="RktVar">literal-constant</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">cons</span><span class="hspace"> </span><span class="RktVar">pattern</span><span class="hspace"> </span><span class="RktVar">pattern</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">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktVar">structure-name</span><span class="hspace"> </span><span class="RktVar">pattern</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">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktSym">?</span><span class="hspace"> </span><span class="RktVar">predicate-name</span><span class="RktPn">)</span></td></tr></table></blockq
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktSym">expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span><span class="hspace"> </span><span class="RktSym">expr</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span><span class="hspace"> </span><span class="RktSym">expr</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></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">proceeds like 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 in that it evaluates
|
||
|
<span class="RktSym">expr</span> and sequentially tries to match its result with
|
||
|
<span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span>, <span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>, ... until it
|
||
|
succeeds with <span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">i</span></span><span style="font-style: italic"></span>. At that point, it determines the
|
||
|
value of <span class="RktSym">expr</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">i</span></span><span style="font-style: italic"></span>, which is also the result of the entire
|
||
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> expression.</div></p><p><div class="SIntrapara">The key difference is that <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>, unlike <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>, introduces a
|
||
|
new scope, which is best illustrated with a screen shot from DrRacket:
|
||
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.603515625px; margin: -3px -3px -3px -3px;" src="pict_139.png" alt="image" width="229.236328125" height="100.0"/></p></blockquote></div><div class="SIntrapara">As the image shows, each pattern clause of this function binds variables.
|
||
|
Furthermore, the scope of a variable is the body of the clause, so even if
|
||
|
two patterns introduce the same variable binding—<wbr></wbr>as is the case in the
|
||
|
above code snippet—<wbr></wbr>their bindings cannot interfere with each other.</div></p><p><div class="SIntrapara">Syntactically, a pattern resembles nested, <a name="(idx._(gentag._490))"></a>structural data whose
|
||
|
leafs are literal constants, variables, or predicate patterns of the shape
|
||
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">?</span><span class="hspace"> </span><span class="RktSym">predicate-name</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">In the latter, <span class="RktSym">predicate-name</span> must
|
||
|
refer to a predicate function in scope, that is, a function that consumes
|
||
|
one value and produces a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>.</div></p><p>Semantically, a pattern is <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>ed to a value <span class="RktSym">v</span>. If the
|
||
|
pattern is</p><p><div class="SIntrapara"><ul><li><p>a <span class="RktSym">literal-constant</span>, it matches only that literal constant</p><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktVal">4</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">'</span><span class="RktVal">four</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">"four"</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">#true</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">"hello world"</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">"hello world"</span></p></td></tr></table></blockquote></li><li><p>a <span class="RktSym">variable</span>, it matches any value, and it is associated with this
|
||
|
value during the evaluation of the body of the corresponding <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> clause</p><p><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">"one"</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</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._%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><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">5</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Since <span class="RktVal">2</span> does not equal the first pattern, which is the literal
|
||
|
constant <span class="RktVal">3</span>, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> matches <span class="RktVal">2</span> with the second
|
||
|
pattern, which is a plain variable and thus matches any value. Hence, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>
|
||
|
picks the second clause and evaluates its body, with <span class="RktSym">x</span> standing
|
||
|
for <span class="RktVal">2</span>.</div></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">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span><span class="stt"> </span><span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span><span class="RktPn">)</span>,
|
||
|
it matches only an instance 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>, assuming its first field matches
|
||
|
<span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span> and its rest matches <span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span></p><p><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</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">1</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="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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </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#%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">head</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">head</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">'()</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</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">2</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="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..
|
||
|
then uses literal constants and variables for the leafs of the given list.</div></p></li><li><p><span class="RktPn">(</span><span class="RktSym">structure-name</span><span class="stt"> </span><span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></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">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span><span class="RktPn">)</span>,
|
||
|
it matches only a <span class="RktSym">structure-name</span> structure, assuming its field values
|
||
|
match <span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>1<span style="font-style: italic"></span></span><span style="font-style: italic"></span>, ..., <span class="RktSym">pattern</span><span style="font-style: italic"></span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span></p><p><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#%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">p</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktSym">p</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">posn</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="RktPn">(</span><span class="RktSym"><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="RktPn">(</span><span class="RktSym"><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._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="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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">y</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><span class="RktRes">5</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Obviously, matching an instance of <span class="RktSym">posn</span> with a pattern is
|
||
|
just like matching 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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> pattern. Note, though, how the pattern
|
||
|
uses <span class="RktSym">posn</span> for the pattern, not the name of the constructor.</div></p><p><div class="SIntrapara">Matching also works for our own structure type definitions:
|
||
|
</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#%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">phone</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">area</span><span class="hspace"> </span><span class="RktSym">switch</span><span class="hspace"> </span><span class="RktSym">four</span><span class="RktPn">]</span><span class="RktPn">)</span></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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-phone</span><span class="hspace"> </span><span class="RktVal">713</span><span class="hspace"> </span><span class="RktVal">664</span><span class="hspace"> </span><span class="RktVal">9993</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">phone</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">y</span><span class="hspace"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">11370</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Again, the pattern uses the name of the structure, <span class="RktSym">phone</span>.</div></p><p><div class="SIntrapara">Finally, matching also works across several layers of constructions:
|
||
|
</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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</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="RktPn">(</span><span class="RktSym">make-phone</span><span class="hspace"> </span><span class="RktVal">713</span><span class="hspace"> </span><span class="RktVal">664</span><span class="hspace"> </span><span class="RktVal">9993</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="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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">phone</span><span class="hspace"> </span><span class="RktSym">area-code</span><span class="hspace"> </span><span class="RktVal">664</span><span class="hspace"> </span><span class="RktVal">9993</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktSym">area-code</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">713</span></p></td></tr></table></blockquote></div><div class="SIntrapara">This <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> expression extracts the area code from a phone number in a
|
||
|
list if the <span class="RktSym">switch</span> code is <span class="RktVal">664</span> and the last four digits are
|
||
|
<span class="RktVal">9993</span>.</div></p></li><li><p><span class="RktPn">(</span><span class="RktSym">?</span><span class="stt"> </span><span class="RktSym">predicate-name</span><span class="RktPn">)</span>, it matches when <span class="RktPn">(</span><span class="RktSym">predicate-name</span><span class="stt"> </span><span class="RktSym">v</span><span class="RktPn">)</span>
|
||
|
produces <span class="RktVal">#true</span></p><p><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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</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">1</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="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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">?</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._symbol~3f%29%29" class="RktValLink" data-pltdoc="x">symbol?</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </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#%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">head</span><span class="hspace"> </span><span class="RktSym">tail</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">head</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">1</span></p></td></tr></table></blockquote></div><div class="SIntrapara">This expression produces <span class="RktVal">1</span>, the result of the second clause, because
|
||
|
<span class="RktVal">1</span> is not a symbol.</div></p></li></ul></div><div class="SIntrapara">Stop! Experiment with <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> before you read on.</div></p><p><div class="SIntrapara">At this point, it is time to demonstrate the usefulness of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>:
|
||
|
</div><div class="SIntrapara"><blockquote><p><div class="SIntrapara"><span style="font-weight: bold">Sample Problem</span> Design the function <span class="RktSym">last-item</span>, which retrieves the last item on a
|
||
|
non-empty list. Recall that non-empty lists are defined as follows:
|
||
|
</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._non._empty._list)"></a><span style="font-style: italic">Non-empty-list</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="RktPn">(</span><span class="RktSym"><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">X</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</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="RktSym">X</span><span class="stt"> </span><span class="RktPn">[</span><a href="i3-4.html#%28tech._non._empty._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">Non-empty-list</span></a><span class="stt"> </span><span class="RktSym">X</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p></blockquote></div><div class="SIntrapara">Stop! <a href="part_two.html" data-pltdoc="x">Arbitrarily Large Data</a> deals with this problem. Look up the solution.</div></p><p><div class="SIntrapara">With <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>, a designer can eliminate three selectors and two predicates
|
||
|
from the solution 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._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>:<a name="(idx._(gentag._491))"></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="i3-4.html#%28tech._non._empty._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">Non-empty-list</span></a><span class="RktCmt"> X] -> X</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">retrieves the last item of </span><span class="RktSym">ne-l</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-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last-item</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="hspace"> </span><span class="RktVal">'</span><span class="RktVal">c</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-error%29%29" class="RktStxLink" data-pltdoc="x">check-error</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last-item</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="RktPn">(</span><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">last-item</span><span class="hspace"> </span><span class="RktSym">ne-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/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktSym">ne-l</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">lst</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">lst</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://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">fst</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">last-item</span><span class="hspace"> </span>
|
||
|
like those found in the data definition. For each self-reference and occurrence
|
||
|
of the set parameter in the data definition, the patterns use program-level
|
||
|
variables. The bodies of the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> clauses no longer extract the
|
||
|
relevant parts from the list with selectors but simply refer to these names. As
|
||
|
before, the function recurs on 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._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field of the given
|
||
|
<span class="RktSym"><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> because the data definition refers to itself in this
|
||
|
position. In the base case, the answer is <span class="RktSym">lst</span>, the variable that stands
|
||
|
for the last item on the list.</div></p><p>Let’s take a look at a second problem from <a href="part_two.html" data-pltdoc="x">Arbitrarily Large Data</a>:</p><blockquote><p><div class="SIntrapara"><span style="font-weight: bold">Sample Problem</span> Design the function <span class="RktSym">depth</span>, which measures the number of
|
||
|
layers surrounding a Russian doll. Here is the data definition again:
|
||
|
</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">layer</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._color%29%29" class="RktValLink" data-pltdoc="x">color</a></span><span class="hspace"> </span><span class="RktSym">doll</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._rd..v2)"></a><span style="font-style: italic">RD.v2</span><span class="RktCmt"> (short for </span><span style="font-style: italic">Russian doll</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">"doll"</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">make-layer</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="i3-4.html#%28tech._rd..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD.v2</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div></p></blockquote><p><div class="SIntrapara">Here is a definition of <span class="RktSym">depth</span> using <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span>:<a name="(idx._(gentag._492))"></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="i3-4.html#%28tech._rd..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD.v2</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></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">how many dolls are a part of </span><span class="RktSym">an-rd</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-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="hspace"> </span><span class="RktVal">"doll"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</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">depth</span><span class="hspace"> </span><span class="RktSym">a-doll</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/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktSym">a-doll</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVal">"doll"</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="RktPn">(</span><span class="RktSym">layer</span><span class="hspace"> </span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktSym">inside</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">depth</span><span class="hspace"> </span><span class="RktSym">inside</span><span class="RktPn">)</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></td></tr></table></blockquote></div><div class="SIntrapara">While the pattern in the first <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> clause looks for
|
||
|
<span class="RktVal">"doll"</span>, the second one matches any <span class="RktSym">layer</span> structure,
|
||
|
associating <span class="RktSym">c</span> with the value in the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._color%29%29" class="RktValLink" data-pltdoc="x">color</a></span> field and
|
||
|
<span class="RktSym">inside</span> with the value in the <span class="RktSym">doll</span> field. In short,
|
||
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpabstraction.html#%28form._x._%28%28lib._teachpack%2F2htdp%2Fabstraction..rkt%29._match%29%29" class="RktStxLink" data-pltdoc="x">match</a></span> again makes the function definition concise.</div></p><p><div class="SIntrapara">The final problem is an excerpt from the generalized UFO game:
|
||
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design the <span class="RktSym">move-right</span> function. It consumes a list
|
||
|
of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, which represent the positions of objects on a canvas,
|
||
|
plus a number. The function adds the latter to each x-coordinate, which
|
||
|
represents a rightward movement of these objects.</p></blockquote></div><div class="SIntrapara">Here is our solution, using the full power of ISL+:<a name="(idx._(gentag._493))"></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">moves each object right by </span><span class="RktSym">delta-x</span><span class="RktCmt"> pixels</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">input</span><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><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">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><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">10</span><span class="hspace"> </span><span class="RktVal">14</span><span class="RktPn">)</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._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">expect</span><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><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">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><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">13</span><span class="hspace"> </span><span class="RktVal">14</span><span class="RktPn">)</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="
|
||
|
If you give data examples good names 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._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span> and write down
|
||
|
next to them what a function produces as the expected result, you can read
|
||
|
the code later much more easily than if you had just written down the
|
||
|
constants.</div></p><p>Stop! How does a solution 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._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> and selectors compare? Write
|
||
|
it out and compare the two. Which one do you like better?</p><p><a name="(counter._(exercise._ex~3awork4-again))"></a><span style="font-weight: bold">Exercise</span> 308. Design the function <span class="RktSym">replace</span>,
|
||
|
which substitutes the area code <span class="RktVal">713</span> with <span class="RktVal">281</span> in a list of
|
||
|
phone records. <a href="i3-4.html#%28counter._%28exercise._ex~3awork4-again%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3awords-on-line-match))"></a><span style="font-weight: bold">Exercise</span> 309. Design the function
|
||
|
<span class="RktSym">words-on-line</span>, which determines the number of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s per
|
||
|
item in a list of list of strings. <a href="i3-4.html#%28counter._%28exercise._ex~3awords-on-line-match%29%29" class="ex-end" data-pltdoc="x"></a></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="part_three.html" title="backward to "III Abstraction"" 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="part_four.html" title="forward to "IV Intertwined Data"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html>
|