emacs.d/clones/lisp/htdp.org/2022-8-7/Book/part_six.html

976 lines
No EOL
570 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>VI&nbsp;Accumulators</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,&quot;tocview_0&quot;);">&#9660;</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"> &nbsp;</span> How to Program</a></td></tr><tr><td align="right">I&nbsp;</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&nbsp;</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&nbsp;</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="tocviewlink" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a></td></tr><tr><td align="right">IV&nbsp;</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&nbsp;</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&nbsp;</td><td><a href="part_six.html" class="tocviewselflink" 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"> &nbsp;</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,&quot;tocview_1&quot;);">&#9658;</a></td><td>VI&nbsp;</td><td><a href="part_six.html" class="tocviewselflink" data-pltdoc="x">Accumulators</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">31&nbsp;</td><td><a href="part_six.html#%28part._ch~3aaccumulator-samples%29" class="tocviewlink" data-pltdoc="x">The Loss of Knowledge</a></td></tr><tr><td align="right">32&nbsp;</td><td><a href="part_six.html#%28part._sec~3adesign-accu%29" class="tocviewlink" data-pltdoc="x">Designing Accumulator-<wbr></wbr>Style Functions</a></td></tr><tr><td align="right">33&nbsp;</td><td><a href="part_six.html#%28part._ch~3amore-accu%29" class="tocviewlink" data-pltdoc="x">More Uses of Accumulation</a></td></tr><tr><td align="right">34&nbsp;</td><td><a href="part_six.html#%28part._ch~3asummary6%29" class="tocviewlink" data-pltdoc="x">Summary</a></td></tr></table></div></div></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="version">8.6.0.2</span></div><div class="navsettop"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;<span class="tocsettoggle">&nbsp;&nbsp;<a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright">&nbsp;&nbsp;<a href="i5-6.html" title="backward to &quot;Intermezzo 5: The Cost of Computation&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;How to Design Programs, Second Edition&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="part_epilogue.html" title="forward to &quot;Epilogue: Moving On&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div><h3>VI<tt>&nbsp;</tt><a name="(part._part~3asix)"></a>Accumulators</h3><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._ch~3aaccumulator-samples%29" class="toclink" data-pltdoc="x">31<span class="hspace">&nbsp;</span>The Loss of Knowledge</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3aloss~3astructural%29" class="toclink" data-pltdoc="x">31.1<span class="hspace">&nbsp;</span>A Problem with Structural Processing</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3aloss~3agenerative%29" class="toclink" data-pltdoc="x">31.2<span class="hspace">&nbsp;</span>A Problem with Generative Recursion</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3adesign-accu%29" class="toclink" data-pltdoc="x">32<span class="hspace">&nbsp;</span>Designing Accumulator-Style Functions</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3aneed-accu%29" class="toclink" data-pltdoc="x">32.1<span class="hspace">&nbsp;</span>Recognizing the Need for an Accumulator</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3aaccu-style%29" class="toclink" data-pltdoc="x">32.2<span class="hspace">&nbsp;</span>Adding Accumulators</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3atrans-accu%29" class="toclink" data-pltdoc="x">32.3<span class="hspace">&nbsp;</span>Transforming Functions into Accumulator Style</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._accu-edit._sec~3aedit3%29" class="toclink" data-pltdoc="x">32.4<span class="hspace">&nbsp;</span>A Graphical Editor, with Mouse</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._ch~3amore-accu%29" class="toclink" data-pltdoc="x">33<span class="hspace">&nbsp;</span>More Uses of Accumulation</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3amore-accu-trees%29" class="toclink" data-pltdoc="x">33.1<span class="hspace">&nbsp;</span>Accumulators and Trees</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3amore-accu-mc%29" class="toclink" data-pltdoc="x">33.2<span class="hspace">&nbsp;</span>Data Representations with Accumulators</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._sec~3afractal-acc%29" class="toclink" data-pltdoc="x">33.3<span class="hspace">&nbsp;</span>Accumulators as Results</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="part_six.html#%28part._ch~3asummary6%29" class="toclink" data-pltdoc="x">34<span class="hspace">&nbsp;</span>Summary</a></p></td></tr></table><p>When you ask ISL+ to apply some function <span class="RktSym">f</span> to an argument
<span class="RktSym">a</span>, you usually get some value <span class="RktSym">v</span>. If you evaluate
<span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">a</span><span class="RktPn">)</span> again, you get <span class="RktSym">v</span> again. As a matter of fact, you
get <span class="RktSym">v</span> no matter how often you request the evaluation of
<span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">a</span><span class="RktPn">)</span>.<span class="refelem"><span class="refcolumn"><span class="refcontent">The function application may also loop
forever or signal an error, but we ignore these possibilities. We also
ignore <span class="RktSym">random</span>, which is the true exception to this rule.</span></span></span>
Whether the function is applied for the first time or the hundredth time,
whether the application is located in DrRacket&rsquo;s interactions area or inside
the function itself, doesn&rsquo;t matter. The function works according to its
purpose statement, and that&rsquo;s all you need to know.</p><p>This principle of context-independence plays a critical role in the design
of recursive functions. When it comes to design, you are free to assume
that the function computes what the purpose statement promises&#8212;<wbr></wbr>even if
the function isn&rsquo;t defined yet. In particular, you are free to use the
results of recursive calls to create the code of some function, usually in
one of its <span class="RktSym">cond</span> clauses. The template and coding steps of the
design recipes for both <a name="(idx._(gentag._705))"></a>structurally and <a name="(idx._(gentag._706))"></a>generative-recursive functions
rely on this idea.</p><p>While context-independence facilitates the design of functions, it causes
two problems. In general, context-independence induces a loss of knowledge
during a recursive evaluation; a function does not &ldquo;know&rdquo; whether it is
called on a complete list or on a piece of that list. For structurally
recursive programs, this loss of knowledge means that they may have to
traverse data more than once, inducing a performance cost. For functions
that employ generative recursion, the loss means that the function may not
be able to compute the result at all. The preceding part illustrates this
second problem with a graph traversal function that cannot find a path
between two nodes for a circular graph.</p><p>This part introduces a variant of the design recipes to address this &ldquo;loss
of context&rdquo; problem. Since we wish to retain the principle that
<span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">a</span><span class="RktPn">)</span> returns the same result no matter how often or where it is
evaluated, the only solution is to add <span style="font-weight: bold">an argument that represents
the context</span> of the function call. We call this additional argument an
<span style="font-style: italic">accumulator</span>. During the traversal of data, the recursive calls
continue to receive regular arguments while accumulators change in
relation to those and the context.</p><p>Designing functions with accumulators correctly is clearly more complex
than any of the design approaches from the preceding chapters. The key is
to understand the relationship between the proper arguments and the
accumulators. The following chapters explain how to design functions with
accumulators and how they work.</p><h3>31<tt>&nbsp;</tt><a name="(part._ch~3aaccumulator-samples)"></a>The Loss of Knowledge</h3><p>Both functions designed according to structural recipes and the <a name="(idx._(gentag._707))"></a>generative
one suffer from the loss of knowledge, though in different ways. This
chapter explains with two examples&#8212;<wbr></wbr>one from each category&#8212;<wbr></wbr>how the lack
of contextual knowledge affects the performance of functions. While the
first section is about structural recursion, the second one addresses
concerns in the generative realm.</p><h4>31.1<tt>&nbsp;</tt><a name="(part._sec~3aloss~3astructural)"></a>A Problem with Structural Processing</h4><p>Let&rsquo;s start with a seemingly straightforward example:</p><blockquote><p><span style="font-weight: bold">Sample Problem</span> You are working for a geometer team that will measure the length
of road segments. The team asked you to design a program that translates these
relative distances between a series of road points into absolute distances from
some starting point.</p></blockquote><p><div class="SIntrapara">For example, we might be given a line such as this:
</div><div class="SIntrapara"><blockquote><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_273.png" alt="image" width="406.0" height="58.0"/></p></blockquote></div><div class="SIntrapara">Each number specifies the distance between two dots. What we need is the
following picture, where each dot is annotated with the distance to the
left-most end:
</div><div class="SIntrapara"><blockquote><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_274.png" alt="image" width="406.0" height="58.0"/></p></blockquote></div></p><p>Designing a program that performs this calculation is a mere
exercise in structural function design. <a href="part_six.html#%28counter._%28figure._fig~3arel-abs-dist%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">177</span></a>
contains the complete program. When the given list is not <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>,
the natural recursion computes the absolute distance of the remainder of
the dots to the first one on <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span>. Because the first
is not the actual origin and has a distance of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> to the
origin, we must add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> to each number on the result of
the natural recursion. This second step&#8212;<wbr></wbr>adding a number to each item on a
list of numbers&#8212;<wbr></wbr>requires an auxiliary function.</p><p><div class="SIntrapara"><a name="(idx._(gentag._708))"></a>
<a name="(idx._(gentag._709))"></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">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">converts a list of relative to absolute distances</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">the first number represents the distance to the origin</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">40</span><span class="hspace">&nbsp;</span><span class="RktVal">70</span><span class="hspace">&nbsp;</span><span class="RktVal">30</span><span class="hspace">&nbsp;</span><span class="RktVal">30</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">90</span><span class="hspace">&nbsp;</span><span class="RktVal">160</span><span class="hspace">&nbsp;</span><span class="RktVal">190</span><span class="hspace">&nbsp;</span><span class="RktVal">220</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktSym">rest-of-l</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">adjusted</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-each</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">rest-of-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">adjusted</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">adds </span><span class="RktSym">n</span><span class="RktCmt"> to each number on </span><span class="RktSym">l</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-each</span><span class="hspace">&nbsp;</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">40</span><span class="hspace">&nbsp;</span><span class="RktVal">110</span><span class="hspace">&nbsp;</span><span class="RktVal">140</span><span class="hspace">&nbsp;</span><span class="RktVal">170</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">90</span><span class="hspace">&nbsp;</span><span class="RktVal">160</span><span class="hspace">&nbsp;</span><span class="RktVal">190</span><span class="hspace">&nbsp;</span><span class="RktVal">220</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-each</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-each</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3arel-abs-dist))" x-target-lift="Figure"></a>Figure&nbsp;177: </span>Converting relative distances to absolute distances</span></p></blockquote></div></p><p><div class="SIntrapara">While designing the program is relatively straightforward, using it on larger
and larger lists reveals a problem. Consider the evaluation of the
following expression:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">size</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">As we increase <span class="RktSym">size</span>, the time needed grows even
faster:</div></p><p><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="right"><p><span class="RktSym">size</span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>1000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>2000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>3000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>4000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>5000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>6000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>7000</p></td></tr><tr><td align="right"><p>time</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>25</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>109</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>234</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>429</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>689</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>978</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>1365</p></td></tr></table></blockquote></div><div class="SIntrapara">Instead of doubling as we go from <span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> to <span style="font-style: italic"></span>2<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> items, the
time quadruples. This is also the approximate relationship for going from
<span style="font-style: italic"></span>2<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> to <span style="font-style: italic"></span>4<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>, and so on.<span class="refelem"><span class="refcolumn"><span class="refcontent">The times will differ
from computer to computer and year to year. These measurements were
conducted in 2017 on a MacMini running OS X 10.11; the previous
measurement took place in 1998, and the times were <span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic">x</span> larger.</span></span></span>
Using the terminology of <a href="i5-6.html" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a>, we say that the function&rsquo;s
performance is <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> where <span style="font-style: italic">n</span> is the length of the given
list.</div></p><p><a name="(counter._(exercise._ex~3aadd-to-each-map))"></a><span style="font-weight: bold">Exercise</span>&nbsp;489. Reformulate <span class="RktSym">add-to-each</span> using
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. <a href="part_six.html#%28counter._%28exercise._ex~3aadd-to-each-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3arel-abs-.O))"></a><span style="font-weight: bold">Exercise</span>&nbsp;490. Develop a formula that describes the abstract
running time of <span class="RktSym">relative-&gt;absolute</span>. <span style="font-weight: bold">Hint</span> Evaluate the
expression
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">size</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">by hand. Start by replacing <span class="RktSym">size</span> with 1, 2, and 3. How many
recursions of <span class="RktSym">relative-&gt;absolute</span> and <span class="RktSym">add-to-each</span> are
required each time? <a href="part_six.html#%28counter._%28exercise._ex~3arel-abs-.O%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p>Considering the simplicity of the problem, the amount of work that the
program performs is surprising. If we were to convert the same list by
hand, we would tally up the total distance and just add it to the relative
distances as we take steps along the line. Why can&rsquo;t a program do so?</p><p><div class="SIntrapara">Let&rsquo;s attempt to design a version of the function that is close to
our manual method. We still start from the list-processing template:
</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Now let&rsquo;s simulate a hand-evaluation:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><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">&nbsp;</span><span class="RktVal">7</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first item of the result list should obviously be <span class="RktVal">3</span>, and it is
easy to construct this list. But, the second one should be <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span>, yet the second instance of <span class="RktSym">relative-&gt;absolute/a</span> has no way of
&ldquo;knowing&rdquo; that the first item of the <span style="font-weight: bold">original</span> list is
<span class="RktVal">3</span>. The &ldquo;knowledge&rdquo; is lost.</div></p><p>Again, the problem is that recursive functions are independent of their
context. A function processes <span class="RktSym">L</span> in <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">N</span><span class="stt"> </span><span class="RktSym">L</span><span class="RktPn">)</span> the same
way as in <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">K</span><span class="stt"> </span><span class="RktSym">L</span><span class="RktPn">)</span>. Indeed, if given <span class="RktSym">L</span> by itself,
it would also process the list in that way.</p><p>To make up for the loss of &ldquo;knowledge,&rdquo; we equip the function with an
additional parameter: <span class="RktSym">accu-dist</span>. The latter represents the
accumulated distance, which is the tally that we keep when we convert a
list of relative distances to a list of absolute distances. Its initial
value must be <span class="RktVal">0</span>. As the function traverses the list, it must add
its numbers to the tally.</p><p><div class="SIntrapara">Here is the revised definition: <a name="(idx._(gentag._710))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="hspace">&nbsp;</span><span class="RktSym">accu-dist</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktSym">tally</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">accu-dist</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">tally</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">tally</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The recursive application consumes the rest of the list and the new
absolute distance of the current point to the origin. Although both
arguments are changing for every call, the change in the second one
strictly depends on the first argument. The function is still a plain
list-processing procedure.</div></p><p><div class="SIntrapara">Now let&rsquo;s evaluate our running example again:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">12</span><span class="hspace">&nbsp;</span><span class="RktSym">???</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">12</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Fill in the question marks in line 4.</div></p><p>The hand-evaluation shows just how much the use of an accumulator
simplifies the conversion process. Each item in the list is processed
once. When <span class="RktSym">relative-&gt;absolute/a</span> reaches the end of the argument
list, the result is completely determined and no further work is needed. In
general, the function performs on the order of <span style="font-style: italic">N</span> natural recursion
steps for a list with <span style="font-style: italic">N</span> items.</p><p>One problem is that, unlike <span class="RktSym">relative-&gt;absolute</span>, the new function
consumes two arguments, not just one. Worse, someone might accidentally
misuse <span class="RktSym">relative-&gt;absolute/a</span> by applying it to a list of numbers
and a number that isn&rsquo;t <span class="RktVal">0</span>. We can solve both problems with a
function definition that uses 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> definition to encapsulate
<span class="RktSym">relative-&gt;absolute/a</span>; <a href="part_six.html#%28counter._%28figure._fig~3arel-abs-human%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">178</span></a> shows the
result. Now, <span class="RktSym">relative-&gt;absolute</span> is indistinguishable from
<span class="RktSym">relative-&gt;absolute.v2</span> with respect to input-output.</p><p><div class="SIntrapara"><a name="(idx._(gentag._711))"></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">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">converts a list of relative to absolute distances</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">the first number represents the distance to the origin</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute.v2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">40</span><span class="hspace">&nbsp;</span><span class="RktVal">70</span><span class="hspace">&nbsp;</span><span class="RktVal">30</span><span class="hspace">&nbsp;</span><span class="RktVal">30</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">50</span><span class="hspace">&nbsp;</span><span class="RktVal">90</span><span class="hspace">&nbsp;</span><span class="RktVal">160</span><span class="hspace">&nbsp;</span><span class="RktVal">190</span><span class="hspace">&nbsp;</span><span class="RktVal">220</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="hspace">&nbsp;</span><span class="RktSym">accu-dist</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktSym">accu</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">accu-dist</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">accu</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">accu</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l0</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3arel-abs-human))" x-target-lift="Figure"></a>Figure&nbsp;178: </span>Converting relative distances with an accumulator</span></p></blockquote></div></p><p><div class="SIntrapara">Now let&rsquo;s look at how this version of the program performs. To this
end, we evaluate
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute.v2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">size</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">and tabulate the results for several values of <span class="RktSym">size</span>:</div></p><p><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="right"><p><span class="RktSym">size</span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>1000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>2000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>3000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>4000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>5000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>6000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>7000</p></td></tr><tr><td align="right"><p>time</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>0</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>0</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>0</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>0</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>0</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>1</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="right"><p>1</p></td></tr></table></blockquote></div><div class="SIntrapara">Amazingly, <span class="RktSym">relative-&gt;absolute.v2</span> never takes more than one second to
process such lists, even for a list of <span style="font-style: italic"></span>7<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> numbers. Comparing this
performance to the one of <span class="RktSym">relative-&gt;absolute</span>, you may think that
accumulators are a miracle cure for all slow-running programs. Unfortunately,
this isn&rsquo;t the case, but when a structurally recursive function has to
re-process the result of the natural recursion you should definitely consider
the use of accumulators. In this particular case, the performance improved from
<span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> to <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span>&#8212;<wbr></wbr>with an additional large reduction in the
constant.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3arel-abs-from-reverse))"></a><span style="font-weight: bold">Exercise</span>&nbsp;491. With a bit of design and a bit of
tinkering, a friend of yours came up with the following solution for the
sample problem:<span class="refelem"><span class="refcolumn"><span class="refcontent">Adrian German and Mardin Yadegar
suggested this exercise.</span></span></span> <a name="(idx._(gentag._712))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">relative-&gt;absolute</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This simple solution merely uses well-known ISL+ functions:
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span>. 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._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>, as you know,
is just a convenience. You may also recall from <a href="part_three.html" data-pltdoc="x">Abstraction</a> that
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> is designable with the design recipes presented in the
first two parts of the book.</div></p><p>Does your friend&rsquo;s solution mean there is no need for our complicated
design in this motivational section? For an answer, see
<a href="part_six.html#%28part._sec~3aneed-accu%29" data-pltdoc="x">Recognizing the Need for an Accumulator</a>, but reflect on the question first. <span style="font-weight: bold">Hint</span> Try to
design <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> on your own. <a href="part_six.html#%28counter._%28exercise._ex~3arel-abs-from-reverse%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>31.2<tt>&nbsp;</tt><a name="(part._sec~3aloss~3agenerative)"></a>A Problem with Generative Recursion</h4><p><div class="SIntrapara">Let&rsquo;s revisit the problem of &ldquo;traveling&rdquo; along a path in a graph:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design an algorithm that checks whether two nodes are
connected in a <span style="font-style: italic">simple graph</span>. In such a graph, each node has
exactly one, directional connection to another, and possibly itself.</p></blockquote></div><div class="SIntrapara"><a href="part_five.html#%28part._ch~3abacktrack%29" data-pltdoc="x">Algorithms that Backtrack</a> covers the variant where the algorithm has to
discover the path. This sample problem is simpler than that because this
section focuses on the design of an accumulator version of the algorithm.</div></p><p>Consider the sample graph in <a href="part_six.html#%28counter._%28figure._fig~3asim-graph%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">179</span></a>. There are six
nodes, <span style="font-style: italic">A</span> through <span style="font-style: italic">F</span>, and six connections. A path from <span style="font-style: italic">A</span>
to <span style="font-style: italic">E</span> must contain <span style="font-style: italic">B</span> and <span style="font-style: italic">C</span>. There is no path, though,
from <span style="font-style: italic">A</span> to <span style="font-style: italic">F</span> or from any other node besides itself.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_275.png" alt="image" width="355.8" height="72.0"/></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><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">&nbsp;</span><span class="RktSym">a-sg</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">B</span><span class="hspace">&nbsp;</span><span class="RktVal">C</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">C</span><span class="hspace">&nbsp;</span><span class="RktVal">E</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">E</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asim-graph))" x-target-lift="Figure"></a>Figure&nbsp;179: </span>A simple graph</span></p></blockquote><p><div class="SIntrapara">The right part of <a href="part_six.html#%28counter._%28figure._fig~3asim-graph%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">179</span></a> shows how to represent this
graph with nested lists. Each node is represented by a list of two symbols. The
first symbol is the label of the node; the second one is the single node
that is reachable from the first one. Here are the relevant data definitions:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._simplegraph)"></a><span style="font-style: italic">SimpleGraph</span><span class="RktCmt"> is a [</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_six.html#%28tech._connection%29" class="techoutside" data-pltdoc="x"><span class="techinside">Connection</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._connection)"></a><span style="font-style: italic">Connection</span><span class="RktCmt"> is a list of two items:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="stt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._node)"></a><span style="font-style: italic">Node</span><span class="RktCmt"> is a </span><a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a><span class="RktCmt">.</span></td></tr></table></blockquote></div><div class="SIntrapara">They are straightforward translations of our informal descriptions.</div></p><p><div class="SIntrapara">We already know that the problem calls for generative recursion, and it is
easy to create the header material: <a name="(idx._(gentag._713))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is there a path from </span><span class="RktSym">origin</span><span class="RktCmt"> to </span><span class="RktSym">destination</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">in the simple graph </span><span class="RktSym">sg</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">What we need are answers to the four basic questions of the recipe for
<a name="(idx._(gentag._714))"></a>generative recursion:
</div><div class="SIntrapara"><ul><li><p>The problem is trivial if <span class="RktSym">origin</span> is the same as
<span class="RktSym">destination</span>.</p></li><li><p>The trivial solution is <span class="RktVal">#true</span>.</p></li><li><p>If <span class="RktSym">origin</span> is not the same as <span class="RktSym">destination</span>,
there is only one thing we can do: step to the immediate neighbor and
search for <span class="RktSym">destination</span> from there.</p></li><li><p>There is no need to do anything if we find the solution to the new problem.
If <span class="RktSym">origin</span>&rsquo;s neighbor is connected to <span class="RktSym">destination</span>,
then so is <span class="RktSym">origin</span>. Otherwise there is no connection.</p></li></ul></div><div class="SIntrapara">From here we just need to express these answers in ISL+ to obtain a
full-fledged program.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._715))"></a>
<a name="(idx._(gentag._716))"></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">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is there a path from </span><span class="RktSym">origin</span><span class="RktCmt"> to </span><span class="RktSym">destination</span><span class="RktCmt"> in </span><span class="RktSym">sg</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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._symbol~3d~3f%29%29" class="RktValLink" data-pltdoc="x">symbol=?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#t</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">destination</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</span></a><span class="RktCmt"> -&gt; </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">determine the node that is connected to </span><span class="RktSym">a-node</span><span class="RktCmt"> in </span><span class="RktSym">sg</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">B</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">G</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"neighbor: not a node"</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktSym">a-node</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"neighbor: not a node"</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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~3d~3f%29%29" class="RktValLink" data-pltdoc="x">symbol=?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a-node</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktSym">a-node</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3apath-exists1))" x-target-lift="Figure"></a>Figure&nbsp;180: </span>Finding a path in a simple graph</span></p></blockquote></div></p><p><a href="part_six.html#%28counter._%28figure._fig~3apath-exists1%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">180</span></a> contains the complete program, including the
function for finding the neighbor of a node in a simple graph&#8212;<wbr></wbr>a
straightforward exercise in structural recursion&#8212;<wbr></wbr>and test cases for
both possible outcomes. Don&rsquo;t run the program, however. If you do, be ready with your mouse
to stop the run-away program. Indeed, even a casual look at the function
suggests that we have a problem. Although the function is supposed to
produce <span class="RktVal">#false</span> if there is no path from <span class="RktSym">origin</span> to
<span class="RktSym">destination</span>, the program doesn&rsquo;t contain <span class="RktVal">#false</span>
anywhere. Conversely, we need to ask what the function actually does when
there is no path between two nodes.</p><p><div class="SIntrapara">Take another look at <a href="part_six.html#%28counter._%28figure._fig~3asim-graph%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">179</span></a>. In this simple graph there
is no path from <span style="font-style: italic">C</span> to <span style="font-style: italic">D</span>. The connection that leaves <span style="font-style: italic">C</span>
passes right by <span style="font-style: italic">D</span> and instead goes to <span style="font-style: italic">E</span>. So let&rsquo;s look at a
hand-evaluation:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">C</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><img src="pict_276.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;&nbsp;</span><img src="pict_277.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">B</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;&nbsp;</span><img src="pict_278.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">C</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;&nbsp;</span><img src="pict_279.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It confirms that as the function recurs, it calls itself with the exact same
arguments again and again. In other words, the evaluation never stops.</div></p><p>Our problem with <span class="RktSym">path-exists?</span> is again a loss of &ldquo;knowledge,&rdquo;
similar to that of <span class="RktSym">relative-&gt;absolute</span> above. Like
<span class="RktSym">relative-&gt;absolute</span>, the design of <span class="RktSym">path-exists?</span> uses a
recipe and assumes that recursive calls are independent of their
context. In the case of <span class="RktSym">path-exists?</span> this means, in particular,
that the function doesn&rsquo;t &ldquo;know&rdquo; whether a previous application in the
current chain of recursions received the exact same arguments.</p><p>The solution to this design problem follows the pattern of the preceding
section. We add a parameter, which we call <span class="RktSym">seen</span> and which
represents the accumulated list of starter nodes that the function has
encountered, starting with the original application. Its initial value must
be <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. As the function checks on a specific
<span class="RktSym">origin</span> and moves to its neighbors, <span class="RktSym">origin</span> is
added to <span class="RktSym">seen</span>.</p><p><div class="SIntrapara">Here is a first revision of <span class="RktSym">path-exists?</span>, dubbed
<span class="RktSym">path-exists?/a</span>: <a name="(idx._(gentag._717))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</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_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt">] -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is there a path from </span><span class="RktSym">origin</span><span class="RktCmt"> to </span><span class="RktSym">destination</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">assume</span><span class="RktCmt"> there are no paths for the nodes in </span><span class="RktSym">seen</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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._symbol~3d~3f%29%29" class="RktValLink" data-pltdoc="x">symbol=?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">destination</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">sg</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The addition of the new parameter alone does not solve our problem, but, as
the hand-evaluation of
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">C</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><img src="pict_280.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">shows, it provides the foundation for one:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><img src="pict_281.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">C</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">B</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><img src="pict_282.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktVal">C</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">C</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">D</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">B</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><img src="pict_283.png" alt="image" width="13" height="2"/><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktVal">F</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">B</span><span class="hspace">&nbsp;</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktVal">C</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In contrast to the original function, the revised function no longer calls
itself with the exact same arguments. While the three arguments proper are
again the same for the third recursive application, the accumulator
argument is different from that of the first application. Instead of
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, it is now <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">B</span><span class="stt"> </span><span class="RktVal">E</span><span class="stt"> </span><span class="RktVal">C</span><span class="RktVal">)</span>. The new value tells us that
during the search of a path from <span class="RktVal">'</span><span class="RktVal">C</span> to <span class="RktVal">'</span><span class="RktVal">D</span>, the function
has inspected <span class="RktVal">'</span><span class="RktVal">B</span>, <span class="RktVal">'</span><span class="RktVal">E</span>, and <span class="RktVal">'</span><span class="RktVal">C</span> as starting
points.</div></p><p>All we need to do now is to make the algorithm exploit the accumulated
knowledge. Specifically, the algorithm can determine whether the given
<span class="RktSym">origin</span> is already an item in <span class="RktSym">seen</span>. If so, the
problem is also trivially solvable, yielding <span class="RktVal">#false</span> as the
solution. <a href="part_six.html#%28counter._%28figure._fig~3apath-exists2%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">181</span></a> contains the definition of
<span class="RktSym">path-exists.v2?</span>, which is the revision of <span class="RktSym">path-exists?</span>. The
definition refers to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span>, an ISL+ function.</p><p><div class="SIntrapara"><a name="(idx._(gentag._718))"></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">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is there a path from </span><span class="RktSym">origin</span><span class="RktCmt"> to </span><span class="RktSym">destination</span><span class="RktCmt"> in </span><span class="RktSym">sg</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists.v2?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">E</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists.v2?</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">A</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">F</span><span class="hspace">&nbsp;</span><span class="RktSym">a-sg</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists.v2?</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt"> </span><a href="part_six.html#%28tech._simplegraph%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimpleGraph</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_six.html#%28tech._node%29" class="techoutside" data-pltdoc="x"><span class="techinside">Node</span></a><span class="RktCmt">] -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._symbol~3d~3f%29%29" class="RktValLink" data-pltdoc="x">symbol=?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">destination</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#t</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#f</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">neighbor</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">sg</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">path-exists?/a</span><span class="hspace">&nbsp;</span><span class="RktSym">origin</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3apath-exists2))" x-target-lift="Figure"></a>Figure&nbsp;181: </span>Finding a path in a simple graph with an accumulator</span></p></blockquote></div></p><p>The definition of <span class="RktSym">path-exists.v2?</span> also eliminates the two minor
problems with the first revision. By localizing the definition of the
accumulating function, we can ensure that the first call always uses
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> as the initial value for <span class="RktSym">seen</span>. And,
<span class="RktSym">path-exists.v2?</span> satisfies the exact same signature and purpose
statement as the <span class="RktSym">path-exists?</span> function.</p><p>Still, there is a significant difference between <span class="RktSym">path-exists.v2?</span>
and <span class="RktSym">relative-to-absolute2</span>. Whereas the latter was equivalent to
the original function, <span class="RktSym">path-exists.v2?</span> improves on
<span class="RktSym">path-exists?</span>. While the latter fails to find an answer for some
inputs, <span class="RktSym">path-exists.v2?</span> finds a solution for any simple graph.</p><p><a name="(counter._(exercise._ex~3afind-path-comp))"></a><span style="font-weight: bold">Exercise</span>&nbsp;492. Modify the definitions in
<a href="part_five.html#%28counter._fsm._%28figure._fig~3afind-path-code%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">169</span></a> so that the program produces
<span class="RktVal">#false</span>, even if it encounters the same origin twice. <a href="part_six.html#%28counter._%28exercise._ex~3afind-path-comp%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>32<tt>&nbsp;</tt><a name="(part._sec~3adesign-accu)"></a>Designing Accumulator-Style Functions</h3><p>The preceding chapter illustrates the need for accumulating extra knowledge
with two examples. In one case, accumulation makes it easy to understand
the function and yields one that is far faster than the original
version. In the other case, accumulation is necessary for the function to
work properly. In both cases, though, the need for accumulation becomes apparent
only once a properly designed function exists.</p><p><div class="SIntrapara">Generalizing from the preceding chapter suggests that the design of
accumulator functions has two major aspects:
</div><div class="SIntrapara"><ol><li><p>the recognition that a function benefits from an accumulator; and</p></li><li><p>an understanding of what the accumulator represents.</p></li></ol></div><div class="SIntrapara">The first two sections address these two questions. Because the second
one is a difficult topic, the third section illustrates it with a series
of examples that convert regular functions into accumulating ones.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._719))"></a>
<a name="(idx._(gentag._720))"></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">&nbsp;</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] -&gt; [</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">&nbsp;</span><span class="RktCmt">constructs the reverse of </span><span class="RktSym">alox</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">a</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">X [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -&gt; [</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">&nbsp;</span><span class="RktCmt">adds </span><span class="RktSym">an-x</span><span class="RktCmt"> to the end of </span><span class="RktSym">alox</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">a</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktSym">an-x</span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">an-x</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktSym">an-x</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adesign-accu-ex))" x-target-lift="Figure"></a>Figure&nbsp;182: </span>Design with accumulators, a structural example</span></p></blockquote></div></p><h4>32.1<tt>&nbsp;</tt><a name="(part._sec~3aneed-accu)"></a>Recognizing the Need for an Accumulator</h4><p><div class="SIntrapara">Recognizing the need for accumulators is not an easy task. We have seen two
reasons, and they are the most prevalent ones. In either case, it is
critical that we first built a complete function based on a
<span style="font-weight: bold">conventional</span> <a name="(idx._(gentag._721))"></a>design recipe. Then we study the function and proceed
as follows:
</div><div class="SIntrapara"><ol><li><p>If a <a name="(idx._(gentag._722))"></a>structurally recursive function traverses the result of its
natural recursion with an auxiliary, recursive function, consider the use
of an accumulator parameter.</p><p>Take a look at the definition of <span class="RktSym">invert</span> in
<a href="part_six.html#%28counter._%28figure._fig~3adesign-accu-ex%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">182</span></a>. The result of the recursive application
produces the reverse of the rest of the list. It uses <span class="RktSym">add-as-last</span>
to add the first item to this reversed list and thus creates the reverse of
the entire list. This second, auxiliary function is also recursive. We
have thus identified an accumulator candidate.</p><p><div class="SIntrapara">It is now time to study some hand-evaluations, as in <a href="part_six.html#%28part._sec~3aloss~3astructural%29" data-pltdoc="x">A Problem with Structural Processing</a>,
to see whether an accumulator helps. Consider the following:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span>...</td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-as-last</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">a</span><span class="RktVal">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Replace the dots with the two missing steps. Then you can see that
<span class="RktSym">invert</span> eventually reaches the end of the given list&#8212;<wbr></wbr>just like
<span class="RktSym">add-as-last</span>&#8212;<wbr></wbr>and if it knew which items to put there, there would be
no need for the auxiliary function.</div></p></li><li><p>If we are dealing with a function based on generative recursion, we
are faced with a much more difficult task. Our goal must be to understand
whether the algorithm can fail to produce a result for inputs for which we
expect a result. If so, adding a parameter that accumulates knowledge may
help. Because these situations are complex, we defer the discussion of
an example to <a href="part_six.html#%28part._ch~3amore-accu%29" data-pltdoc="x">More Uses of Accumulation</a>.</p></li></ol></div></p><p><a name="(counter._(exercise._ex~3ainvert-.O))"></a><span style="font-weight: bold">Exercise</span>&nbsp;493. Argue that, in the terminology of <a href="i5-6.html" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a>,
<span class="RktSym">invert</span> consumes <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> time when the given list consists
of <span style="font-style: italic">n</span> items. <a href="part_six.html#%28counter._%28exercise._ex~3ainvert-.O%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aneed-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;494. Does the insertion <span class="RktSym">sort&gt;</span> function from
<a href="part_two.html#%28part._sec~3asort.I%29" data-pltdoc="x">Auxiliary Functions that Recur</a> need an accumulator? If so, why? If not, why not? <a href="part_six.html#%28counter._%28exercise._ex~3aneed-accu%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>32.2<tt>&nbsp;</tt><a name="(part._sec~3aaccu-style)"></a>Adding Accumulators</h4><p><div class="SIntrapara">Once you have decided that an existing function should be equipped with an
accumulator, take these two steps:
</div><div class="SIntrapara"><ul><li><p>Determine the knowledge that the accumulator represents, what kind of data
to use, and how the knowledge is acquired as data.</p><p>For example, for the conversion of relative distances to absolute
distances, it suffices to accumulate the total distance encountered so
far. As the function processes the list of relative distances, it adds each
new relative distance found to the accumulator&rsquo;s current value. For the
routing problem, the accumulator remembers every node encountered. As the
path-checking function traverses the graph, it <span class="RktSym"><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>es each new
node on to the accumulator.</p><p><div class="SIntrapara">In general, you will want to proceed as follows.
</div><div class="SIntrapara"><ol><li><p><div class="SIntrapara">Create an <a name="(idx._(gentag._723))"></a>accumulator template:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">Domain -&gt; Range </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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">function</span><span class="hspace">&nbsp;</span><span class="RktSym">d0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">Domain AccuDomain -&gt; Range</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> ...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">function/a</span><span class="hspace">&nbsp;</span><span class="RktSym">d</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">function/a</span><span class="hspace">&nbsp;</span><span class="RktSym">d0</span><span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Sketch a manual evaluation of an application of <span class="RktSym">function</span> to understand
the nature of the accumulator.</div></p></li><li><p>Determine the kind of data that the accumulator tracks.</p><p>Write down a <a name="(idx._(gentag._724))"></a>statement that explains the accumulator as a relationship between
the argument <span class="RktSym">d</span> of the auxiliary <span class="RktSym">function/a</span> and the original
argument <span class="RktSym">d0</span>.</p><p><span style="font-weight: bold">Note</span> The relationship remains constant, also called
<span style="font-weight: bold">invariant</span>, over the course of the evaluation. Because of this
property, an accumulator statement is often called an <span style="font-style: italic">invariant</span>.</p></li><li><p>Use the invariant to determine the initial value <span class="RktSym">a0</span> for
<span class="RktSym">a</span>.</p></li><li><p>Also exploit the invariant to determine how to compute the
accumulator for the recursive function calls within the definition of
<span class="RktSym">function/a</span>.</p></li></ol></div></p></li><li><p>Exploit the accumulator&rsquo;s knowledge for the design of <span class="RktSym">function/a</span>.</p><p>For a structurally recursive function, the accumulator&rsquo;s value is typically used
in the base case, that is, the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause that does not recur. For
functions that use generative-recursive functions, the accumulated knowledge
might be used in an existing base case, in a new base case, or in the
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses that deal with generative recursion.</p></li></ul></div><div class="SIntrapara">As you can see, the key is the precise description of the role of the
<a name="(idx._(gentag._725))"></a>accumulator. It is therefore important to practice this skill.</div></p><p><div class="SIntrapara">Let&rsquo;s take a look at the <span class="RktSym">invert</span> example:<a name="(idx._(gentag._726))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">alox0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</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] ??? -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">constructs the reverse of </span><span class="RktSym">alox</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> ...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><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">a</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><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alox0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As illustrated in the preceding section, this template suffices to sketch a
manual evaluation of an example such as
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">invert</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here is the idea:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><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="RktVal">'</span><span class="RktVal">a</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">a0</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><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="RktVal">'</span><span class="RktVal">b</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="RktVal">'</span><span class="RktVal">a</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">a0</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><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="RktVal">'</span><span class="RktVal">c</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="RktVal">'</span><span class="RktVal">b</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="RktVal">'</span><span class="RktVal">a</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">a0</span></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This sketch suggests that <span class="RktSym">invert/a</span> can keep track of all the items it
has seen in a list that tracks the difference between <span class="RktSym">alox0</span> and
<span class="RktSym">a</span> in reverse order. The initial value is clearly <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>; updating
the accumulator inside of <span class="RktSym">invert/a</span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> produces exactly
the desired value when <span class="RktSym">invert/a</span> reaches <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</div></p><p><div class="SIntrapara">Here is a refined template that includes these insights: <a name="(idx._(gentag._727))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">alox0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">constructs the reverse of </span><span class="RktSym">alox</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> is the list of all those </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">items on </span><span class="RktSym">alox0</span><span class="RktCmt"> that precede </span><span class="RktSym">alox</span><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">in reverse order</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktSym">a</span></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alox</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alox</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">a</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alox0</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">While the body of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> definition initializes the accumulator
with <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, the recursive call uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> to add the current
head of <span class="RktSym">alox</span> to the accumulator. In the base case, <span class="RktSym">invert/a</span>
uses the knowledge in the accumulator, the reversed list.</div></p><p>Note how, once again, <span class="RktSym">invert.v2</span> merely traverses the list. In
contrast, <span class="RktSym">invert</span> reprocesses every result of its natural
recursion with <span class="RktSym">add-as-last</span>. Stop! Measure how much faster
<span class="RktSym">invert.v2</span> runs than <span class="RktSym">invert</span>.</p><p><span style="font-weight: bold">Terminology</span> Programmers use the phrase <span style="font-style: italic">accumulator-style
function</span> to discuss functions that use an accumulator
parameter. Examples of functions in accumulator style are
<span class="RktSym">relative-&gt;absolute/a</span>, <span class="RktSym">invert/a</span>, and <span class="RktSym">path-exists?/a</span>.</p><h4>32.3<tt>&nbsp;</tt><a name="(part._sec~3atrans-accu)"></a>Transforming Functions into Accumulator Style</h4><p>Articulating the accumulator statement is difficult, but, without formulating
a good invariant, it is impossible to understand an accumulator-style
function. Since the goal of a programmer is to make sure that others who
follow understand the code easily, practicing this skill is critical. And
formulating invariants deserves a lot of practice.</p><p>The goal of this section is to study the formulation of accumulator
statements with three case studies: a summation function, the factorial
function, and a tree-traversal function. Each such case is about the
conversion of a structurally recursive function into accumulator
style. None actually calls for the use of an accumulator parameter. But they
are easily understood and, with the elimination of all other distractions,
using such examples allows us to focus on the articulation of the
accumulator invariant.</p><p><div class="SIntrapara">For the first example, consider these definitions of the <span class="RktSym">sum</span>
function: <a name="(idx._(gentag._728))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v1</span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Here is the first step toward an accumulator version: <a name="(idx._(gentag._729))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">alon0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] ??? -&gt; </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes the sum of the numbers on </span><span class="RktSym">alon</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span>...</td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="highlighted"><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">a</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alon0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Supply a signature and a test case that works for both.</div></p><p>As suggested by our first step, we have put the template for <span class="RktSym">sum/a</span>
into 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> definition, added an accumulator parameter, and
renamed the parameter of <span class="RktSym">sum</span> .</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">sum.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td>...</td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">14</span></td></tr></table></td><td><p><span class="hspace">&nbsp;</span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">sum.v2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td>...</td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">14</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asum-accu))" x-target-lift="Figure"></a>Figure&nbsp;183: </span>Calculating with accumulator-style templates</span></p></blockquote><p><div class="SIntrapara"><a href="part_six.html#%28counter._%28figure._fig~3asum-accu%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">183</span></a> shows two side-by-side sketches of
hand-evaluations. A comparison immediately suggests the central idea,
namely,
that <span class="RktSym">sum/a</span> can use the accumulator to add up the numbers it
encounters. Concerning the accumulator invariant, the calculations suggest
<span class="RktSym">a</span> represents the sum of the numbers encountered so far:
</div><div class="SIntrapara"><blockquote><p><span class="RktSym">a</span> is the sum of the numbers that <span class="RktSym">alon</span> lacks from <span class="RktSym">alon0</span></p></blockquote></div><div class="SIntrapara">For example, the invariant forces the following relationships to hold:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left" style="border-bottom: 1px solid black;"><p>if </p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="RktSym">alon0</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p> is </p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">6</span><span class="RktVal">)</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">6</span><span class="RktVal">)</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">6</span><span class="RktVal">)</span></p></td></tr><tr><td align="left"><p>and </p></td><td align="left"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktSym">alon</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p> is </p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">6</span><span class="RktVal">)</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">6</span><span class="RktVal">)</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td></tr><tr><td align="left"><p>then </p></td><td align="left"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktSym">a</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p> should be </p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">10</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">14</span></p></td><td align="right"><p><span class="hspace">&nbsp;</span></p></td><td align="right"><p><span class="RktVal">20</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Given this precise invariant, the rest of the design is straightforward: <a name="(idx._(gentag._730))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">alon0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes the sum of the numbers on </span><span class="RktSym">alon</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> is the sum of the numbers </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">that </span><span class="RktSym">alon</span><span class="RktCmt"> lacks from </span><span class="RktSym">alon0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="hspace">&nbsp;</span><span class="RktSym">alon0</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If <span class="RktSym">alon</span> is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, <span class="RktSym">sum/a</span> returns
<span class="RktSym">a</span> because it represents the sum of all numbers on <span class="RktSym">alon</span>.
The invariant also implies that <span class="RktVal">0</span> is the initial value for
<span class="RktSym">a0</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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span> updates the accumulator by adding the number
that is about to be &ldquo;forgotten&rdquo;&#8212;<wbr></wbr><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alox</span><span class="RktPn">)</span>&#8212;<wbr></wbr>to the
accumulator <span class="RktSym">a</span>.</div></p><p><a name="(counter._(exercise._ex~3asum-accu-inex))"></a><span style="font-weight: bold">Exercise</span>&nbsp;495. Complete the manual evaluation of
<span class="RktPn">(</span><span class="RktSym">sum/a</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> in <a href="part_six.html#%28counter._%28figure._fig~3asum-accu%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">183</span></a>. Doing so
shows that the <span class="RktSym">sum</span> and <span class="RktSym">sum.v2</span> add up the given
numbers in reverse order. While <span class="RktSym">sum</span> adds up the numbers from
right to left, the accumulator-style version adds them up from left to
right.</p><p><span style="font-weight: bold">Note on Numbers</span> Remember that for exact numbers, this difference has
no effect on the final result. For inexact numbers, the difference can be
significant. See the exercises at the end of <a href="i5-6.html" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a>. <a href="part_six.html#%28counter._%28exercise._ex~3asum-accu-inex%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">For the second example, we turn to the well-known factorial
function: <a name="(idx._(gentag._731))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="stt"> </span>...<span class="stt"> </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._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">6</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="refelem"><span class="refcolumn"><span class="refcontent">The factorial function is useful for the analysis of algorithms.</span></span></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">While <span class="RktSym">relative-2-absolute</span> and <span class="RktSym">invert</span> processed lists,
the factorial function works on natural numbers, which its template reflects.</div></p><p><div class="SIntrapara">We proceed as before with a template for an accumulator-style version: <a name="(idx._(gentag._732))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">n0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> ??? -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="stt"> </span>...<span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span>...</td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><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">a</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktSym">n0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">followed by a sketch of a hand-evaluation:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td>...</td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">6</span></td></tr></table></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">!.v2</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span>...<span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="RktPn">)</span></td></tr><tr><td>...</td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">6</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">The left column indicates how the original version works; the right one
sketches how the accumulator-style function proceeds. Both structurally traverse a
natural number until they reach <span class="RktVal">0</span>. While the original version
schedules only multiplications, the accumulator keeps track of each
number as the structural traversal descends through the given natural
number.</div></p><p><div class="SIntrapara">Given the goal of multiplying these numbers, <span class="RktSym">!/a</span> can use the
accumulator to multiply the numbers immediately:
</div><div class="SIntrapara"><blockquote><p><span class="RktSym">a</span> is the product of the natural numbers in the interval [<span class="RktSym">n0</span>,<span class="RktSym">n</span>).</p></blockquote></div><div class="SIntrapara">In particular, when <span class="RktSym">n0</span> is <span class="RktVal">3</span> and <span class="RktSym">n</span> is <span class="RktVal">1</span>,
<span class="RktSym">a</span> is <span class="RktVal">6</span>.</div></p><p><a name="(counter._(exercise._ex~3afactorial-inv))"></a><span style="font-weight: bold">Exercise</span>&nbsp;496. What should the value of <span class="RktSym">a</span> be when
<span class="RktSym">n0</span> is <span class="RktVal">10</span> and <span class="RktSym">n</span> is <span class="RktVal">8</span>? <a href="part_six.html#%28counter._%28exercise._ex~3afactorial-inv%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Using this invariant we can easily pick the initial value for
<span class="RktSym">a</span>&#8212;<wbr></wbr>it is <span class="RktVal">1</span>&#8212;<wbr></wbr>and we know that multiplying the current
accumulator with <span class="RktSym">n</span> is the proper update operation: <a name="(idx._(gentag._733))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">n0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</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"> -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> is the product of the </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">natural numbers in the interval [</span><span class="RktSym">n0</span><span class="RktCmt">,</span><span class="RktSym">n</span><span class="RktCmt">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">!/a</span><span class="hspace">&nbsp;</span><span class="RktSym">n0</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It also follows from the accumulator statement that when <span class="RktSym">n</span> is
<span class="RktVal">0</span>, the accumulator is the product of <span class="RktSym">n</span> through
<span class="RktVal">1</span>, meaning it is the desired result. So, like <span class="RktSym">sum</span>,
<span class="RktSym">!/a</span> returns <span class="RktSym">a</span> in this case and uses the result of the
recursion in the second case.</div></p><p><a name="(counter._(exercise._ex~3atime-factorial))"></a><span style="font-weight: bold">Exercise</span>&nbsp;497. Like <span class="RktSym">sum</span>, <span class="RktSym">!.v1</span><span class="RktMeta"></span> performs the
primitive computations, multiplication in this case, in reverse
order. Surprisingly, this affects the performance of the function in a
negative manner.</p><p>Measure how long it takes to evaluate <span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="stt"> </span><span class="RktVal">20</span><span class="RktPn">)</span> <span style="font-style: italic"></span>1<span style="font-style: italic">,</span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>
times. Recall that <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._time%29%29" class="RktStxLink" data-pltdoc="x">time</a></span><span class="stt"> </span><span class="RktSym">an-expression</span><span class="RktPn">)</span> function determines how
long it takes to run <span class="RktSym">an-expression</span>. <a href="part_six.html#%28counter._%28exercise._ex~3atime-factorial%29%29" class="ex-end" data-pltdoc="x"></a></p><p>For the third and last example, we use a function that measures the height
of simplified binary trees. The example illustrates that accumulator-style
programming applies to all kinds of data, not just those defined with
single self-references. Indeed, it is as commonly used for complicated data
definitions as it is for lists and natural numbers.</p><p><div class="SIntrapara">Here are the relevant 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-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">node</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">left</span><span class="hspace">&nbsp;</span><span class="RktSym">right</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._tree)"></a><span style="font-style: italic">Tree</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="stt"> </span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</span></a><span class="stt"> </span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</span></a><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">&nbsp;</span><span class="RktSym">example</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">These trees carry no information; their leaves are <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. Still,
there are many different trees, as <a href="part_six.html#%28counter._%28figure._fig~3asim-bt-ex%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">184</span></a> shows; it
also uses suggestive graphics to bring across what these pieces of data
look like as trees.</div></p><p><div class="SIntrapara">One property that one may wish to compute is the height of such a tree: <a name="(idx._(gentag._734))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._max%29%29" class="RktValLink" data-pltdoc="x">max</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-left</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-right</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</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">Stop! Supply a signature and a test.
The table in <a href="part_six.html#%28counter._%28figure._fig~3asim-bt-ex%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">184</span></a> indicates how to measure the
height of a tree, though it leaves the notion somewhat ambiguous: it is
either the number of nodes from the root of the tree to the highest leaf
or the number of connections on such a path. The <span class="RktSym">height</span> function
follows the second option.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="bottom"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_284.png" alt="image" width="206.0" height="31.0"/></p></td><td valign="bottom"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="bottom"><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td valign="bottom"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_285.png" alt="image" width="206.0" height="106.0"/></p></td><td valign="bottom"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="bottom"><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td valign="bottom"><p><span class="hspace">&nbsp;</span></p></td><td valign="bottom"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="bottom"><p><span class="hspace">&nbsp;</span></p></td></tr><tr><td valign="bottom"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_286.png" alt="image" width="206.0" height="231.0"/></p></td><td valign="bottom"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="bottom"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">make-node</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asim-bt-ex))" x-target-lift="Figure"></a>Figure&nbsp;184: </span>Some stripped-down binary trees</span></p></blockquote><p><div class="SIntrapara">To transform this function into an accumulator-style function, we follow the
standard path. We begin with an appropriate template: <a name="(idx._(gentag._735))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</span></a><span class="RktCmt"> ??? -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">measures the height of </span><span class="RktSym">abt</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span>...</td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-left</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><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">a</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-right</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><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">a</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As always, the problem is to determine what knowledge the accumulator
represents. One obvious choice is the number of traversed branches:
</div><div class="SIntrapara"><blockquote><p><span class="RktSym">a</span> is the number of steps it takes to reach
<span class="RktSym">abt</span> from <span class="RktSym">abt0</span>.</p></blockquote></div></p><p><div class="SIntrapara">Illustrating this accumulator invariant is best done with a graphical example.
Take a second look at <a href="part_six.html#%28counter._%28figure._fig~3asim-bt-ex%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">184</span></a>. The bottom-most tree comes
with two annotations, each pointing out one subtree:
</div><div class="SIntrapara"><ol><li><p>If <span class="RktSym">abt0</span> is the complete tree and <span class="RktSym">abt</span> is the subtree
pointed to by the circled <span style="font-style: italic"></span>1<span style="font-style: italic"></span>, the accumulator&rsquo;s value must be <span class="RktVal">1</span> because it
takes exactly one step to get from the root of <span class="RktSym">abt</span> to the root of
<span class="RktSym">abt0</span>.</p></li><li><p>In the same spirit, for the subtree labeled <span style="font-style: italic"></span>2<span style="font-style: italic"></span> the accumulator is
<span class="RktVal">2</span> because it takes two steps to get to this place.</p></li></ol></div></p><p><div class="SIntrapara">As for the preceding two examples, the invariant basically dictates how to follow
the rest of the <a name="(idx._(gentag._736))"></a>design recipe for accumulators: the initial value for <span class="RktSym">a</span>
is <span class="RktVal">0</span>; the update operation 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._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span>; and the base case uses the
accumulated knowledge by returning it. Translating this into code yields the
following skeleton definition: <a name="(idx._(gentag._737))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</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"> -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">measures the height of </span><span class="RktSym">abt</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> is the number of steps </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">it takes to reach </span><span class="RktSym">abt</span><span class="RktCmt"> from </span><span class="RktSym">abt0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-left</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-right</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">But, in contrast to the first two examples, <span class="RktSym">a</span> is not the final
result. In the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause, the two recursive calls yield two
values. The design recipe for structural functions dictates that we combine those
in order to formulate an answer for this case; the dots above indicate that we
still need to pick an operation that combines these values.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._738))"></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">&nbsp;</span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</span></a><span class="RktCmt"> -&gt; </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">&nbsp;</span><span class="RktCmt">measures the height of </span><span class="RktSym">abt0</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">example</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">3</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</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"> -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">measures the height of </span><span class="RktSym">abt</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> is the number of steps </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">it takes to reach </span><span class="RktSym">abt</span><span class="RktCmt"> from </span><span class="RktSym">abt0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._max%29%29" class="RktValLink" data-pltdoc="x">max</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-left</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-right</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">height/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt0</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aheight-accu))" x-target-lift="Figure"></a>Figure&nbsp;185: </span>The accumulator-style version of <span style="font-style: italic">height</span></span></p></blockquote></div></p><p>Following the design recipe also tells us that we need to interpret the two
values to find the appropriate function. According to the purpose statement for
<span class="RktSym">height/a</span>, the first value is the height of the left subtree, and the
second one is the height of the right one. Given that we are interested in the
height of <span class="RktSym">abt</span> itself and that the height is the largest number of steps
it takes to reach a leaf, we use 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._max%29%29" class="RktValLink" data-pltdoc="x">max</a></span> function to pick the proper
one; see <a href="part_six.html#%28counter._%28figure._fig~3aheight-accu%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">185</span></a> for the complete definition.</p><p><div class="SIntrapara"><span style="font-weight: bold">Note on an Alternative Design</span> In addition to counting the number of
steps it takes to reach a node, an accumulator function could hold on to
the largest height encountered so far. Here is the accumulator statement
for the design idea:
</div><div class="SIntrapara"><blockquote><p>The first accumulator represents the
number of steps it takes to reach <span class="RktSym">abt</span> from (the root of)
<span class="RktSym">abt0</span>. The second one stands for the height of the part in
<span class="RktSym">abt0</span> that is strictly to the left of <span class="RktSym">abt</span>.</p></blockquote></div><div class="SIntrapara">Clearly, this statement assumes a template with two accumulator
parameters, something we have not encountered before:
<a name="(idx._(gentag._739))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._tree%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tree</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"> -&gt; </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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">measures the height of </span><span class="RktSym">abt</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">s</span><span class="RktCmt"> is the number of steps </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">it takes to reach </span><span class="RktSym">abt</span><span class="RktCmt"> from </span><span class="RktSym">abt0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">m</span><span class="RktCmt"> is the maximal height of</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">the part of </span><span class="RktSym">abt0</span><span class="RktCmt"> that is to the left of </span><span class="RktSym">abt</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">h/a</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="hspace">&nbsp;</span><span class="RktSym">m</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">h/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-left</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><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">s</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><span class="hspace">&nbsp;</span><span class="highlighted"><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">m</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">h/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">node-right</span><span class="hspace">&nbsp;</span><span class="RktSym">abt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><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">s</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><span class="hspace">&nbsp;</span><span class="highlighted"><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">m</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><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr></table></blockquote></div></p><p><a name="(counter._(exercise._ex~3aheight-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;498. Complete <span class="RktSym">height.v3</span>.
<span style="font-weight: bold">Hint</span> The bottom-most tree of <a href="part_six.html#%28counter._%28figure._fig~3asim-bt-ex%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">184</span></a>
contains no subtree to the left of the subtree marked with <span style="font-style: italic"></span>1<span style="font-style: italic"></span>.
It contains one complete path from root to tree in the part of the tree
that is to the left of the subtree marked with <span style="font-style: italic"></span>2<span style="font-style: italic"></span>; this path consists
of two steps. <a href="part_six.html#%28counter._%28exercise._ex~3aheight-accu%29%29" class="ex-end" data-pltdoc="x"></a></p><p>This second design has a more complex accumulator invariant than the first
one. By implication, its implementation requires more care than the first
one. At the same time, it comes without any obvious advantages.</p><p>Our point is that different accumulator invariants yield different
variants. You can design both variants systematically, following the same
design recipe. When you have complete function definitions, you can compare
and contrast the results, and you can then decide which one to keep, based
on evidence. <span style="font-weight: bold">End</span></p><p><a name="(counter._(exercise._ex~3api-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;499. Design an accumulator-style version of
<span class="RktSym">product</span>, the function that computes the product of a list of
numbers. Stop when you have formulated the accumulator invariant and have
someone check it.</p><p>The performance of <span class="RktSym">product</span> is <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span> where <span style="font-style: italic">n</span> is the
length of the list. Does the accumulator version improve on this? <a href="part_six.html#%28counter._%28exercise._ex~3api-accu%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3alength-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;500. Design an accumulator-style version of
<span class="RktSym">how-many</span>, which is the function that determines the number of
items on a list. Stop when you have formulated the invariant
and have someone check it.</p><p>The performance of <span class="RktSym">how-many</span> is <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span> where <span style="font-style: italic">n</span> is the
length of the list. Does the accumulator version improve on this?</p><p>When you evaluate <span class="RktPn">(</span><span class="RktSym">how-many</span><span class="stt"> </span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span> by hand, <span style="font-style: italic">n</span>
applications 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._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span> are pending by the time the function reaches
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>&#8212;<wbr></wbr>where <span style="font-style: italic">n</span> is the number of items on the list. Computer
scientists sometime say that <span class="RktSym">how-many</span> needs <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span> space to
<span class="refelem"><span class="refcolumn"><span class="refcontent">Computer scientists refer to this space as <span style="font-style: italic">stack
space</span>, but you can safely ignore this terminology for now.</span></span></span>
represent these pending function applications. Does the accumulator reduce
the amount of space needed to compute the result? <a href="part_six.html#%28counter._%28exercise._ex~3alength-accu%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aadd-pi-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;501. Design an accumulator-style version of
<span class="RktSym">add-to-pi</span>. The function adds a natural number to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span> without using
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span>: <a name="(idx._(gentag._740))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -&gt; </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">&nbsp;</span><span class="RktCmt">adds </span><span class="RktSym">n</span><span class="RktCmt"> to </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktCmt"> without using </span><span class="RktSym"><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></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-within%29%29" class="RktStxLink" data-pltdoc="x">check-within</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-pi</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0.001</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-pi</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-pi</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop when you have formulated the accumulator invariant and have someone check it. <a href="part_six.html#%28counter._%28exercise._ex~3aadd-pi-accu%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3apalindrome))"></a><span style="font-weight: bold">Exercise</span>&nbsp;502. Design the function <span class="RktSym">palindrome</span>, which
accepts a non-empty list and constructs a palindrome by mirroring the list around
the last item. When given <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="stt"> </span><span class="RktVal">"abc"</span><span class="RktPn">)</span>, it yields <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="stt"> </span><span class="RktVal">"abcba"</span><span class="RktPn">)</span>.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hint</span> Here is a solution designed by function composition: <a name="(idx._(gentag._741))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[</span><a href="part_three.html#%28tech._sim-dd._nelist._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">] -&gt; [</span><a href="part_three.html#%28tech._sim-dd._nelist._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">creates a palindrome from </span><span class="RktSym">s0</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">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mirror</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"abc"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"abcba"</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mirror</span><span class="hspace">&nbsp;</span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">all-but-last</span><span class="hspace">&nbsp;</span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace">&nbsp;</span><span class="RktSym">s0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">all-but-last</span><span class="hspace">&nbsp;</span><span class="RktSym">s0</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">See <a href="part_two.html#%28part._sec~3agen-funcs%29" data-pltdoc="x">Auxiliary Functions that Generalize</a> for <span class="RktSym">last</span>; design <span class="RktSym">all-but-last</span> in an
analogous manner.</div></p><p><div class="SIntrapara">This solution traverses <span class="RktSym">s0</span> four times:
</div><div class="SIntrapara"><ol><li><p>via <span class="RktSym">all-but-last</span>,</p></li><li><p>via <span class="RktSym">last</span>,</p></li><li><p>via <span class="RktSym">all-but-last</span> again, and</p></li><li><p>via <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span>, which is ISL+&rsquo;s version of <span class="RktSym">invert</span>.</p></li></ol></div><div class="SIntrapara">Even with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> definition for the result of <span class="RktSym">all-but-last</span>, the
function needs three traversals. While these traversals aren&rsquo;t &ldquo;stacked&rdquo; and
therefore don&rsquo;t have a disastrous impact on the function&rsquo;s performance, an
accumulator version can compute the same result with a single traversal. <a href="part_six.html#%28counter._%28exercise._ex~3apalindrome%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3agauss-fast))"></a><span style="font-weight: bold">Exercise</span>&nbsp;503. <a href="part_five.html#%28counter._%28exercise._ex~3atriangulate2%29%29" data-pltdoc="x">Exercise&nbsp;467</a> implicitly asks for the
design of a function that rotates a <a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a> until the first
coefficient of the first row differs from <span class="RktVal">0</span>. In the context of
<a href="part_five.html#%28counter._%28exercise._ex~3atriangulate2%29%29" data-pltdoc="x">Exercise&nbsp;467</a>, the solution calls for a generative-recursive
function that creates a new matrix by shifting the first row to the end
when it encounters a <span class="RktVal">0</span> in the first position. Here is the solution:
<a name="(idx._(gentag._742))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">finds a row that doesn</span><span class="RktCmt">'</span><span class="RktCmt">t start with 0 and</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">uses it as the first one</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">generative</span><span class="RktCmt"> moves the first row to last place </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">no termination</span><span class="RktCmt"> if all rows start with </span><span class="RktVal">0</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">&nbsp;</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._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://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">&nbsp;</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._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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._not%29%29" class="RktValLink" data-pltdoc="x">not</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Modify this function so that it signals an error when all rows start
with <span class="RktVal">0</span>.</div></p><p><div class="SIntrapara">If you measure this function on large instances of <a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a>, you get a
surprising result:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="right"><p>rows in <span class="RktSym">M</span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="center"><p>1000</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>2000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>3000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>4000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5000</p></td></tr><tr><td align="right"><p><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="center"><p>17</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>66</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>151</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>272</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>436</p></td></tr></table></blockquote></div><div class="SIntrapara">As the number of rows increases from <span style="font-style: italic"></span>1<span style="font-style: italic">,</span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> to <span style="font-style: italic"></span>5<span style="font-style: italic">,</span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>, the time
spent by <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span> does not increase by a factor of five but by twenty.</div></p><p><div class="SIntrapara">The problem is that <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span> uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span>, which makes a
brand-new list like <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">M</span><span class="RktPn">)</span> only to add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">M</span><span class="RktPn">)</span> at the
end. If <span class="RktSym">M</span> consists of <span style="font-style: italic"></span>1<span style="font-style: italic">,</span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> rows and the last row is the
only one with a non-<span class="RktVal">0</span> coefficient, that&rsquo;s roughly
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_287.png" alt="image" width="140" height="10"/></p></blockquote></div><div class="SIntrapara">lists. How many lists do we get if <span class="RktSym">M</span> consists of <span style="font-style: italic"></span>5<span style="font-style: italic">,</span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>
lines?</div></p><p><div class="SIntrapara">Now suppose we conjecture that the accumulator-style version is
faster than the generative one. Here is the accumulator template for a
structurally recursive version of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._rotate%29%29" class="RktValLink" data-pltdoc="x">rotate</a></span>:
<a name="(idx._(gentag._743))"></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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">rotate.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">M0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktCmt"> </span>...<span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span>...</td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">rotate/a</span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="hspace">&nbsp;</span><span class="RktSym">seen</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">Can this be simplified to </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">M</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">rotate/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">M</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktSym">seen</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">rotate/a</span><span class="hspace">&nbsp;</span><span class="RktSym">M0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The goal is to remember the first row when its leading coefficient is
<span class="RktVal">0</span> without using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span> for every recursion.</div></p><p>Formulate an accumulator statement. Then follow the accumulator design
recipe to complete the above function. Measure how fast it runs on a
<span class="RktSym">Matrix</span> that consists of rows with leading <span class="RktVal">0</span>s except for
the last one. If you completed the design correctly, the function is quite fast. <a href="part_six.html#%28counter._%28exercise._ex~3agauss-fast%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3ato10))"></a><span style="font-weight: bold">Exercise</span>&nbsp;504. Design <span class="RktSym">to10</span>. It consumes a list of digits and produces the
corresponding number. The first item on the list is the <span style="font-weight: bold">most significant</span>
digit. Hence, when applied to <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span>, it produces <span class="RktVal">102</span>.</p><p><span style="font-weight: bold">Domain Knowledge</span> You may recall from grade school that the result is determined by
<img src="pict_288.png" alt="image" width="299" height="13"/> <a href="part_six.html#%28counter._%28exercise._ex~3ato10%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3ais-prime))"></a><span style="font-weight: bold">Exercise</span>&nbsp;505. Design the function <span class="RktSym">is-prime</span>, which consumes a
natural number and returns <span class="RktVal">#true</span> if it is prime and <span class="RktVal">#false</span>
otherwise.</p><p><span style="font-weight: bold">Domain Knowledge</span> A number <span style="font-style: italic">n</span> is prime if it is not divisible by any
number between <span style="font-style: italic">n - </span>1<span style="font-style: italic"></span> and <span style="font-style: italic"></span>2<span style="font-style: italic"></span>.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hint</span> The design recipe for <a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a> [&gt;=1] suggests the following template:
<a name="(idx._(gentag._744))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> [&gt;=1] -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">determines whether </span><span class="RktSym">n</span><span class="RktCmt"> is a prime number</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">is-prime?</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">is-prime?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This template immediately tells you that the function forgets <span class="RktSym">n</span>, its
initial argument as it recurs. Since <span class="RktSym">n</span> is definitely needed to determine
whether <span class="RktSym">n</span> is divisible by <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span>, <span class="RktPn">(</span><span class="RktSym"><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">2</span><span class="RktPn">)</span>, and so on,
you know that you need an accumulator-style function. <a href="part_six.html#%28counter._%28exercise._ex~3ais-prime%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Speed</span> Programmers who encounter accumulator-style functions for
the first time often get the impression that they are always faster than
their plain counterparts. So let&rsquo;s take a look at the solution of
<a href="part_six.html#%28counter._%28exercise._ex~3atime-factorial%29%29" data-pltdoc="x">exercise&nbsp;497</a>:<span class="refelem"><span class="refcolumn"><span class="refcontent">An explanation of these times is
beyond the scope of this book.</span></span></span>
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="right"><p><span class="RktSym">!.v1</span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.760</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.780</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.800</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.820</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.870</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p><span class="highlighted"><span class="RktVal">5.806</span></span></p></td></tr><tr><td align="right"><p><span class="RktSym">!.v2</span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.970</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.940</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.980</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>5.970</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>6.690</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p><span class="highlighted"><span class="RktVal">6.111</span></span></p></td></tr></table></blockquote></div><div class="SIntrapara">The table&rsquo;s top row shows the number of seconds for five runs of
<span class="RktPn">(</span><span class="RktSym">!.v1</span><span class="stt"> </span><span class="RktVal">20</span><span class="RktPn">)</span>, while the bottom one lists those of running
<span class="RktPn">(</span><span class="RktSym">!.v2</span><span class="stt"> </span><span class="RktVal">20</span><span class="RktPn">)</span>. The last column shows the averages. In short, the table
shows that people jump to premature conclusions; the performance of at
least one accumulator-style function is worse than that of the
original. <span style="font-weight: bold">Do not trust prejudices.</span> Instead, measure performance
characteristics of your programs for yourself. <span style="font-weight: bold">End</span></div></p><p><a name="(counter._(exercise._ex~3amap-accu))"></a><span style="font-weight: bold">Exercise</span>&nbsp;506. Design an accumulator-style version of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>. <a href="part_six.html#%28counter._%28exercise._ex~3amap-accu%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afoldl-designed))"></a><span style="font-weight: bold">Exercise</span>&nbsp;507. <a href="part_three.html#%28counter._%28exercise._ex~3adesigning-build-list%29%29" data-pltdoc="x">Exercise&nbsp;257</a> explains how
to design <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> with the design recipes and guidelines of the
first two parts of the book: <a name="(idx._(gentag._745))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">version 1</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">That 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._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span> is the result of reversing the given list and then
using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> to fold the given function over this intermediate list.</div></p><p><div class="SIntrapara">The <span class="RktSym">f*ldl</span> function obviously traverses the list twice, but once
we design all the functions, it becomes clear how much harder it has to work:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">version 2</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-end</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-end</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-to-end</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We know that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> has to traverse a list once for
every item on the list, meaning <span class="RktSym">f*ldl</span> really performs
<img src="pict_289.png" alt="image" width="12" height="10"/> traversals for a list of length <span style="font-style: italic">n</span>. Fortunately, we
know how to eliminate this bottleneck with an accumulator:
<a name="(idx._(gentag._746))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">version 3</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">invert/a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Once <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> uses an accumulator, we actually get the apparent
performance of two traversals of the list. The question is whether we can
improve on this by adding an accumulator to the locally defined
<span class="RktSym">fold</span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">version 4</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">fold/a</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">fold/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">fold/a</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._e%29%29" class="RktValLink" data-pltdoc="x">e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since equipping the function with an accumulator reverses the order in
which the list is traversed, the initial reversal of the list is
superfluous.</div></p><p><div class="SIntrapara"><span style="font-weight: bold">Task 1</span> Recall the signature for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">[X Y] [X Y -&gt; Y] Y [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> X] -&gt; Y</span></p></blockquote></div><div class="SIntrapara">It is also the signature of <span class="RktSym">f*ldl</span>. Formulate the signature for
<span class="RktSym">fold/a</span> and its accumulator invariant. <span style="font-weight: bold">Hint</span> Assume that the
difference between <span class="RktSym">l0</span> and <span class="RktSym">l</span> is <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">x1</span><span class="stt"> </span><span class="RktSym">x2</span><span class="stt"> </span><span class="RktSym">x3</span><span class="RktPn">)</span>. What is <span class="RktSym">a</span>, then?</div></p><p><div class="SIntrapara">You may also be wondering why <span class="RktSym">fold/a</span> consumes its arguments in
this unusual order, first the accumulator and then the list. To understand
the reason for this ordering, imagine instead that <span class="RktSym">fold/a</span> also
consumes <span class="RktSym">f</span>&#8212;<wbr></wbr>as the first argument. At this point it becomes
abundantly clear that <span class="RktSym">fold/a</span> 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._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">version 5</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">i</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">i</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f*ldl</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">i</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><span style="font-weight: bold">Task 2</span> Design <span class="RktSym">build-l*st</span> using an accumulator-style
approach. The function must satisfy the following tests:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">build-l*st</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">for any natural number <span class="RktSym">n</span> and function <span class="RktSym">f</span>. <a href="part_six.html#%28counter._%28exercise._ex~3afoldl-designed%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>32.4<tt>&nbsp;</tt><a name="(part._accu-edit._sec~3aedit3)"></a>A Graphical Editor, with Mouse</h4><p><a href="part_one.html#%28part._sec~3aedit1%29" data-pltdoc="x">A Graphical Editor</a> introduces the notion of a one-line editor and presents
a number of exercises on creating a graphical editor. Recall that a
graphical editor is an interactive program that interprets key events as
editing actions on a string. In particular, when a user presses the left or
right arrow keys, the cursor moves left or right; similarly, pressing the
delete key removes a <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a> from the edited text. The editor
program uses a <a name="(idx._accu-edit._(gentag._747._accu-edit))"></a>data representation that combines two strings in a
structure. <a href="part_two.html#%28part._list-edit2._sec~3aedit2%29" data-pltdoc="x">A Graphical Editor, Revisited</a> resumes these
exercises and shows how the same program can greatly benefit from a
different data structure, one that combines two strings.</p><p>Neither of these sections deals with mouse actions for navigation, even
though all modern applications support this functionality. The basic
difficulty with mouse events is to place the cursor at the appropriate
spot. Since the program deals with a single line of text, a mouse click at
<span style="font-style: italic"></span>(<span style="font-style: italic">x,y</span>)<span style="font-style: italic"></span> clearly aims to place the cursor between the letters that are
visible at or around the <span style="font-style: italic">x</span> position. This section fills the gap.</p><p>Recall the relevant definitions from <a href="part_two.html#%28part._list-edit2._sec~3aedit2%29" data-pltdoc="x">A Graphical Editor, Revisited</a>:
<a name="(idx._accu-edit._(gentag._748._accu-edit))"></a></p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">FONT-SIZE</span><span class="hspace">&nbsp;</span><span class="RktVal">11</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">&nbsp;</span><span class="RktSym">FONT-COLOR</span><span class="hspace">&nbsp;</span><span class="RktVal">"black"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</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._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">] -&gt; </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">renders a string as an image for the editor </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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</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._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">FONT-SIZE</span><span class="hspace">&nbsp;</span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">editor</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">pre</span><span class="hspace">&nbsp;</span><span class="RktSym">post</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._accu-edit._editor)"></a><span style="font-style: italic">Editor</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="stt"> </span><span class="RktPn">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="stt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktPn">]</span><span class="stt"> </span><span class="RktPn">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="stt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> if </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="stt"> </span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktCmt"> is the state of </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">an interactive editor, </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktCmt"> corresponds to</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">the text to the left of the cursor and </span><span class="RktSym">s</span><span class="RktCmt"> to the</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">text on the right </span></td></tr></table></blockquote><p><div class="SIntrapara"><a name="(counter._accu-edit._(exercise._ex~3aeditor-mouse-structural))"></a><span style="font-weight: bold">Exercise</span>&nbsp;508. Design <span class="RktSym">split-structural</span>
using the structural design recipe. The function consumes a list of
<a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s <span class="RktSym">ed</span> and a natural number <span class="RktSym">x</span>; the former
represents the complete string in some <a href="part_six.html#%28tech._accu-edit._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a> and the latter the
x-coordinate of the mouse click. The function produces
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace">&nbsp;</span><span class="RktSym">p</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">such that (1) <span class="RktSym">p</span> and <span class="RktSym">s</span> make up <span class="RktSym">ed</span> and (2) <span style="font-style: italic">x</span>
is larger than the image of <span class="RktSym">p</span> and smaller than the image of
<span class="RktSym">p</span> extended with the first <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a> on <span class="RktSym">s</span> (if any).</div></p><p><div class="SIntrapara">Here is the first condition expressed with an ISL+ expression:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace">&nbsp;</span><span class="RktSym">p</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">ed</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The second one is
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c~3d%29%29" class="RktValLink" data-pltdoc="x">&lt;=</a></span><span class="hspace">&nbsp;</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._image-width%29%29" class="RktValLink" data-pltdoc="x">image-width</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace">&nbsp;</span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">x</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</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._image-width%29%29" class="RktValLink" data-pltdoc="x">image-width</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace">&nbsp;</span><span class="RktSym">p</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">assuming <span class="RktPn">(</span><span class="RktSym"><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~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span>.</div></p><p><span style="font-weight: bold">Hints</span> (1) The x-coordinate measures the distance from the
left. Hence the function must check whether larger and larger prefixes of
<span class="RktSym">ed</span> fit into the given width. The first one that doesn&rsquo;t fit
corresponds to the <span class="RktSym">pre</span> field of the desired <a href="part_six.html#%28tech._accu-edit._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>, the
remainder of <span class="RktSym">ed</span> to the <span class="RktSym">post</span> field.</p><p>(2) Designing this function calls for thoroughly developing examples and
tests. See <a href="part_one.html#%28part._ch~3aintervals-enums%29" data-pltdoc="x">Intervals, Enumerations, and Itemizations</a>. <a href="part_six.html#%28counter._accu-edit._%28exercise._ex~3aeditor-mouse-structural%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._accu-edit._(exercise._ex~3aeditor-mouse))"></a><span style="font-weight: bold">Exercise</span>&nbsp;509. Design the function <span class="RktSym">split</span>. Use the
accumulator design recipe to improve on the result of
<a href="part_six.html#%28counter._accu-edit._%28exercise._ex~3aeditor-mouse-structural%29%29" data-pltdoc="x">exercise&nbsp;508</a>. After all, the hints already point out
that when the function discovers the correct split point, it needs both
parts of the list, and one part is obviously lost due to recursion. <a href="part_six.html#%28counter._accu-edit._%28exercise._ex~3aeditor-mouse%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Once you have solved this exercise, equip the <span class="RktSym">main</span> function of
<a href="part_two.html#%28part._list-edit2._sec~3aedit2%29" data-pltdoc="x">A Graphical Editor, Revisited</a> with a clause for mouse
clicks. As you experiment with moving the cursor via mouse clicks, you will
notice that it does not exactly behave like applications that you use on
your other devices&#8212;<wbr></wbr>even though <span class="RktSym">split</span> passes all its
tests.</p><p>Graphical programs, like editors, call for experimentation to come up with the
best &ldquo;look and feel&rdquo; experiences. In this case, your editor is too
simplistic with its placement of the cursor. After the applications on your
computer determine the split point, they also determine which letter
division is closer to the x-coordinate and place the cursor
there.</p><p><a name="(counter._accu-edit._(exercise._ex~3afmt))"></a><span style="font-weight: bold">Exercise</span>&nbsp;510. Many operating systems come with the <span class="stt">fmt</span> program,
which can rearrange the words in a file so that all lines in the resulting
file have a maximal width. As a widely used program, <span class="stt">fmt</span> supports a
range of related functions. This exercise focuses on its core functionality.</p><p>Design the program <span class="RktSym">fmt</span>. It consumes a natural number <span class="RktSym">w</span>,
the name of an input file <span class="RktSym">in-f</span>, and the name of an output file
<span class="RktSym">out-f</span>&#8212;<wbr></wbr>in the same sense as <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-file%29%29" class="RktValLink" data-pltdoc="x">read-file</a></span> from
<span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/batch-io</span></span> teachpack</span>. Its purpose is to read all the words from the
<span class="RktSym">in-f</span>, to arrange these words in the given order into lines of
maximal width <span class="RktSym">w</span>, and to write these lines to <span class="RktSym">out-f</span>. <a href="part_six.html#%28counter._accu-edit._%28exercise._ex~3afmt%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>33<tt>&nbsp;</tt><a name="(part._ch~3amore-accu)"></a>More Uses of Accumulation</h3><p>This chapter presents three more uses of accumulators. The first section
concerns the use of accumulators in conjunction with tree-processing
functions. It uses the compilation of ISL+ as an illustrative
example. The second section explains why we occasionally want accumulators
inside of data representations and how to go about placing them there. The
final section resumes the discussion of rendering fractals.</p><h4>33.1<tt>&nbsp;</tt><a name="(part._sec~3amore-accu-trees)"></a>Accumulators and Trees</h4><p>When you ask DrRacket to run an ISL+ program, it translates the program to
commands for your specific computer. This process is called
<span style="font-style: italic">compilation</span>, and the part of DrRacket that performs the task is
called a <span style="font-style: italic">compiler</span>. Before the compiler translates the ISL+
program, it checks that every variable is declared via a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span>,
a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span>, or 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>.</p><p>Stop! Enter <span class="RktSym">x</span>, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span>, and <span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span> as
complete ISL+ programs into DrRacket and ask it to run each. What do you
expect to see?</p><p><div class="SIntrapara">Let&rsquo;s phrase this idea as a sample problem:
</div><div class="SIntrapara"><blockquote><p><div class="SIntrapara"><span style="font-weight: bold">Sample Problem</span> You have been hired to re-create a part of the ISL+
compiler. Specifically, your task deals with the following language
fragment, specified in the so-called grammar notation that many programming
language manuals use:<span class="refelem"><span class="refcolumn"><span class="refcontent">We use the Greek letter &#955; instead of
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> to signal that this exercise deals with ISL+ as an
object of study, not just a programming language.</span></span></span>
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td align="right" valign="baseline"><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">expression</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktVar">variable</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktVar">variable</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVar">expression</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">(</span><span class="RktVar">expression</span><span class="hspace">&nbsp;</span><span class="RktVar">expression</span><span class="RktPn">)</span></td></tr></table></div><div class="SIntrapara">Remember from intermezzo 1 that you can read the grammar
aloud replacing <span class="RktInBG"><span class="hspace"></span><span class="RktIn">=</span><span class="hspace"></span></span> with &ldquo;is one of&rdquo; and <span class="RktInBG"><span class="hspace"></span><span class="RktIn">|</span><span class="hspace"></span></span> with &ldquo;or.&rdquo;</div></p><p>Recall that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span> expressions are functions without names. They bind
their parameter in their body. Conversely, a variable occurrence is
declared by a surrounding <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span> that specifies the same name as a
parameter. You may wish to revisit <a href="i3-4.html" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a> because it deals with the
same issue from the perspective of a programmer. Look for the terms &ldquo;binding
occurrence,&rdquo; &ldquo;bound occurrence,&rdquo; and &ldquo;free.&rdquo;</p><p>Develop a data representation for the above language fragment; use symbols
to represent variables. Then design a function that replaces all undeclared
variables with <span class="RktVal">'</span><span class="RktVal">*undeclared</span>.</p></blockquote></div><div class="SIntrapara">This problem is representative of many steps in the translation process
and, at the same time, is a great case study for accumulator-style
functions.</div></p><p><div class="SIntrapara">Before we dive into the problem, let&rsquo;s look at some examples in this
mini-language, recalling what we know about <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>:
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span> is the function that returns whatever it is given,
also known as the identity function;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span> looks like a function that returns <span class="RktSym">y</span>
whenever it is given an argument, except that <span class="RktSym">y</span> isn&rsquo;t declared;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span> is a function that, when given some value
<span class="RktSym">v</span>, produces a function that always returns <span class="RktSym">v</span>;</p></li><li><p><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><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._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span> applies the identity function to itself;</p></li><li><p><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span> is a short infinite loop; and</p></li><li><p><span class="RktPn">(</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._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">z</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">z</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">w</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span> is a complex
expression that is best run in ISL+ to find out whether it terminates.</p></li></ul></div><div class="SIntrapara">Indeed, you can run all of the above ISL+ expressions in DrRacket to confirm
what is written about them.</div></p><p><a name="(counter._(exercise._ex~3abinding1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;511. Explain the scope of each binding occurrence in
the above examples. Draw arrows from the bound to the binding occurrences. <a href="part_six.html#%28counter._%28exercise._ex~3abinding1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Developing a data representation for the language is easy, especially
because its description uses a grammar notation. Here is one possibility:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._lam)"></a><span style="font-style: italic">Lam</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> a </span><a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">&#955;</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a><span class="RktPn">)</span><span class="stt"> </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="stt"> </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Because 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._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</a></span>, this data representation makes it easy to
create data representations for expressions in our subset of ISL+:
</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">&nbsp;</span><span class="RktSym">ex1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">x</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">&nbsp;</span><span class="RktSym">ex2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">y</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">&nbsp;</span><span class="RktSym">ex3</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">y</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">y</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://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">&nbsp;</span><span class="RktSym">ex4</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">These four data examples are representations of some of the above
expressions. Stop! Create data representations for the remaining examples.</div></p><p><a name="(counter._(exercise._ex~3afree-bound-access))"></a><span style="font-weight: bold">Exercise</span>&nbsp;512. Define <span class="RktSym">is-var?</span>, <span class="RktSym">is-&#955;?</span>,
and <span class="RktSym">is-app?</span>, that is, predicates that distinguish variables from &#955; expressions and applications.</p><p><div class="SIntrapara">Also define
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">&#955;-para</span>, which extracts the parameter from a &#955; expression;</p></li><li><p><span class="RktSym">&#955;-body</span>, which extracts the body from a &#955; expression;</p></li><li><p><span class="RktSym">app-fun</span>, which extracts the function from an application; and</p></li><li><p><span class="RktSym">app-arg</span>, which extracts the argument from an application.</p></li></ul></div><div class="SIntrapara">With these predicates and selectors, you basically can act as if you had
defined a structure-oriented data representation.</div></p><p>Design <span class="RktSym">declareds</span>, which produces the list of all symbols used as &#955;
parameters in a &#955; term. Don&rsquo;t worry about duplicate symbols. <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-access%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afree-bound-dd0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;513. Develop a data representation for the same
subset of ISL+ that uses structures instead of lists. Also provide data
representations for <span class="RktSym">ex1</span>, <span class="RktSym">ex2</span>, and <span class="RktSym">ex3</span> following
your data definition. <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-dd0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">We follow the structural design recipe, and here is the product of
steps two and three: <a name="(idx._(gentag._749))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktCmt"> -&gt; </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">replaces all symbols </span><span class="RktSym">s</span><span class="RktCmt"> in </span><span class="RktSym">le</span><span class="RktCmt"> with </span><span class="RktVal">'</span><span class="RktVal">*undeclared</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">if they do not occur within the body of a &#955; </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">expression whose parameter is </span><span class="RktSym">s</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">ex1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">ex1</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">ex2</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">*undeclared</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">ex3</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">ex3</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">ex4</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">ex4</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">le0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">le0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Note how we expect <span class="RktSym">undeclareds</span> to process <span class="RktSym">ex4</span> even though
the expression loops forever when run; compilers don&rsquo;t run programs, they
read them and create others.</div></p><p><div class="SIntrapara">A close look at the purpose statement directly suggests that the function
needs an accumulator. This becomes even clearer when we inspect the
template for <span class="RktSym">undeclareds</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-var?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-&#955;?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">&#955;-body</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-app?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-fun</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-arg</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">When <span class="RktSym">undeclareds</span> recurs on the body of (the representation of) a &#955;
expression, it forgets <span class="RktPn">(</span><span class="RktSym">&#955;-para</span><span class="stt"> </span><span class="RktSym">le</span><span class="RktPn">)</span>, the declared variable.</div></p><p><div class="SIntrapara">So, let&rsquo;s start with an accumulator-style template:
</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">le0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktCmt"> ??? -&gt; </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">a</span><span class="RktCmt"> represents ... </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-var?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-&#955;?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">&#955;-body</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-app?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-fun</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-arg</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><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">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">le0</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In this context, we can now formulate an accumulator invariant:
</div><div class="SIntrapara"><blockquote><p><span class="RktSym">a</span> represents the list of &#955; parameters encountered on the path from
the top of <span class="RktSym">le0</span> to the top of <span class="RktSym">le</span>.</p></blockquote></div><div class="SIntrapara">For example, if <span class="RktSym">le0</span> is
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">y</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span></span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">w</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">w</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">and <span class="RktSym">le</span> is the highlighted subtree, then <span class="RktSym">a</span> contains
<span class="RktSym">y</span>. The left side of <a href="part_six.html#%28counter._%28figure._fig~3alam-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">186</span></a> presents a graphical
illustration of the same example. It shows a <a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a> expression as an
upside-down tree; that is, the root is at the top. A <span class="stt">@</span> node represents
an application with two descendants; the other nodes are
self-explanatory. In this tree diagram, the bold path leads from
<span class="RktSym">le0</span> to <span class="RktSym">le</span> through a single variable declaration.</div></p><p><div class="SIntrapara">Similarly, if we pick a different subtree of the same piece of data,
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">y</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktSym">y</span></span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">w</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">w</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">we get an accumulator that contains both <span class="RktVal">'</span><span class="RktVal">y</span> and <span class="RktVal">'</span><span class="RktVal">x</span>.
The right side of <a href="part_six.html#%28counter._%28figure._fig~3alam-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">186</span></a> makes this point again. Here
the bold path leads through two <span class="RktVal">'</span><span class="RktVal">&#955;</span> nodes to the boxed subtree,
and the accumulator is the list of declared variables along the bold
path.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_290.png" alt="image" width="194.0" height="326.0"/>
<span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_291.png" alt="image" width="194.0" height="326.0"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alam-tree))" x-target-lift="Figure"></a>Figure&nbsp;186: </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a> terms as trees</span></p></blockquote><p><div class="SIntrapara">Now that we have settled on the data representation of the accumulator and
its invariant, we can resolve the remaining design questions:
</div><div class="SIntrapara"><ul><li><p>We pick an initial accumulator value of <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</p></li><li><p>We use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> to add <span class="RktPn">(</span><span class="RktSym">&#955;-para</span><span class="stt"> </span><span class="RktSym">le</span><span class="RktPn">)</span> to <span class="RktSym">a</span>.</p></li><li><p>We exploit the accumulator for the clause where
<span class="RktSym">undeclareds/a</span> deals with a variable. Specifically, the function
uses the accumulator to check whether the variable is in the scope of a
declaration.</p></li></ul></div></p><p><a href="part_six.html#%28counter._%28figure._fig~3aundeclareds%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">187</span></a> shows how to translate these ideas into a
complete function definition. Note the name <span class="RktSym">declareds</span> for the
accumulator; it brings across the key idea behind the accumulator
invariant, helping the programmer understand the definition. The base case
uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span> from ISL+ to determine whether the variable
<span class="RktSym">le</span> is in <span class="RktSym">declareds</span> and, if not, replaces it with
<span class="RktVal">'</span><span class="RktVal">*undeclared</span>. The second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause uses 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> to introduce the extended accumulator <span class="RktSym">newd</span>. Because
<span class="RktSym">para</span> is also used to rebuild the expression, it has its own
local definition. Finally, the last clause concerns function applications,
which do not declare variables and do not use any directly. As a result,
it is by far the simplest of the three clauses.</p><p><div class="SIntrapara"><a name="(idx._(gentag._750))"></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">&nbsp;</span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktCmt"> -&gt; </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds</span><span class="hspace">&nbsp;</span><span class="RktSym">le0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</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="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a><span class="RktCmt">] -&gt; </span><a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> </span><span class="RktSym">declareds</span><span class="RktCmt"> is a list of all &#955; </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">parameters on the path from </span><span class="RktSym">le0</span><span class="RktCmt"> to </span><span class="RktSym">le</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="hspace">&nbsp;</span><span class="RktSym">declareds</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-var?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="hspace">&nbsp;</span><span class="RktSym">declareds</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">*undeclared</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-&#955;?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktSym">para</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">&#955;-para</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">body</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">&#955;-body</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">newd</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">para</span><span class="hspace">&nbsp;</span><span class="RktSym">declareds</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">para</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">body</span><span class="hspace">&nbsp;</span><span class="RktSym">newd</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">is-app?</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</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">&nbsp;</span><span class="RktSym">fun</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-fun</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">arg</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">app-arg</span><span class="hspace">&nbsp;</span><span class="RktSym">le</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">fun</span><span class="hspace">&nbsp;</span><span class="RktSym">declareds</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">arg</span><span class="hspace">&nbsp;</span><span class="RktSym">declareds</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">undeclareds/a</span><span class="hspace">&nbsp;</span><span class="RktSym">le0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aundeclareds))" x-target-lift="Figure"></a>Figure&nbsp;187: </span>Finding undeclared variables</span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3afree-bound-both))"></a><span style="font-weight: bold">Exercise</span>&nbsp;514. Make up an ISL+ expression in which
<span class="RktSym">x</span> occurs both free and bound. Formulate it as an element of
<a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a>. Does <span class="RktSym">undeclareds</span> work properly on your expression? <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-both%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afree-bound-undeclared))"></a><span style="font-weight: bold">Exercise</span>&nbsp;515. Consider the following expression:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">*undeclared</span><span class="RktPn">)</span><span class="hspace">&nbsp;</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._~ce~bb%29%29" class="RktStxLink" data-pltdoc="x">&#955;</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">*undeclared</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Yes, it uses <span class="RktSym">*undeclared</span> as a variable. Represent it in <a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a>
and check what <span class="RktSym">undeclareds</span> produces for this expression.</div></p><p><div class="SIntrapara">Modify <span class="RktSym">undeclareds</span> so that it replaces a free occurrence of <span class="RktVal">'</span><span class="RktVal">x</span> with
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">*undeclared</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">x</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">and a bound one <span class="RktVal">'</span><span class="RktVal">y</span> with
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">*declared</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">y</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Doing so unambiguously identifies problem spots, which a program development
environment such as DrRacket can use to highlight errors.</div></p><p><span style="font-weight: bold">Note</span> The trick of replacing a variable occurrence with the
representation of an application feels awkward. If you dislike it, consider
synthesizing the symbols <span class="RktVal">'</span><span class="RktVal">*undeclared:x</span> and <span class="RktVal">'</span><span class="RktVal">declared:y</span>
instead. <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-undeclared%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afree-bound-dd1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;516. Redesign the <span class="RktSym">undeclareds</span> function
for the structure-based data representation from
<a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-dd0%29%29" data-pltdoc="x">exercise&nbsp;513</a>. <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound-dd1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_292.png" alt="image" width="280.0" height="432.0"/>
<span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_293.png" alt="image" width="280.0" height="432.0"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asd))" x-target-lift="Figure"></a>Figure&nbsp;188: </span>Static distances</span></p></blockquote></div><div class="SIntrapara"><a name="(counter._(exercise._ex~3afree-bound1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;517. Design <span class="RktSym">static-distance</span>. The function
replaces all occurrences of variables with a natural number that represents
how far away the declaring &#955; is. <a href="part_six.html#%28counter._%28figure._fig~3asd%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">188</span></a> illustrates the idea
for the term
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">y</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">y</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">&#955;</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">z</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">in graphical form. It includes dotted arrows that point from variable
occurrences to the corresponding variable declarations. On the right, the
figure shows a tree of the same shape, though without the arrows. The
<span class="RktVal">'</span><span class="RktVal">&#955;</span> nodes come without names, and variable occurrences have been
replaced by natural numbers that specify which <span class="RktVal">'</span><span class="RktVal">&#955;</span> declares the
variable. Each natural number <span class="RktSym">n</span> says that the binding occurrence
is <span class="RktSym">n</span> steps upward&#8212;<wbr></wbr>toward the root of the <a href="part_six.html#%28tech._lam%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lam</span></a> tree. A
value of <span class="RktVal">0</span> denotes the first <span class="RktVal">'</span><span class="RktVal">&#955;</span> on the path to the root,
<span class="RktVal">1</span> the second one, and so on.</div></p><p><span style="font-weight: bold">Hint</span> The <span class="RktSym">undeclareds</span> accumulator of <span class="RktSym">undeclareds/a</span>
is a list of all parameters on path from <span class="RktSym">le</span> to <span class="RktSym">le0</span>
<span style="font-weight: bold">in reverse order</span>&#8212;<wbr></wbr>the last one seen is first on the list. <a href="part_six.html#%28counter._%28exercise._ex~3afree-bound1%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>33.2<tt>&nbsp;</tt><a name="(part._sec~3amore-accu-mc)"></a>Data Representations with Accumulators</h4><p>The end of <a href="i5-6.html" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a> explains that <span class="stt">*SL</span> measures the size of
containers, say lists, by traversing them and hints that other programming
languages use a different,<span class="refelem"><span class="refcolumn"><span class="refcontent">See <a href="part_two.html#%28part._sec~3asec-fsm-list%29" data-pltdoc="x">Finite State Machines</a> for
an early example of this idea.</span></span></span> less expensive way, to compute sizes. In
this section, we show how to implement this idea with the <span style="font-weight: bold">addition
of an accumulator to data representations</span>.</p><p>Consider the ubiquitous lists in <span class="stt">*SL</span>. All lists are constructed from
<span class="RktSym"><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> and <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>; operations such as <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>, for example, are merely abbreviations for these two. As
<a href="part_two.html#%28part._sec~3alists-cons%29" data-pltdoc="x">What Is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, What Is <span class="RktSym"><span class="RktValLink">cons</span></span></a> shows, it is also possible to mimic lists in
BSL with suitable structure type and function definitions.</p><p><div class="SIntrapara"><a name="(idx._(gentag._751))"></a>
<a name="(idx._(gentag._752))"></a>
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">pair</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">left</span><span class="hspace">&nbsp;</span><span class="RktSym">right</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-style: italic">ConsOrEmpty</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="stt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="stt"> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace">&nbsp;</span><span class="RktSym">a-value</span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="hspace">&nbsp;</span><span class="RktSym">a-value</span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">pair?</span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="hspace">&nbsp;</span><span class="RktSym">a-value</span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"our-cons: ..."</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">extracts the </span><span class="RktSym">left</span><span class="RktCmt"> part of the given </span><span class="RktSym">pair</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">our-first</span><span class="hspace">&nbsp;</span><span class="RktSym">mimicked-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">mimicked-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"our-first: ..."</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">pair-left</span><span class="hspace">&nbsp;</span><span class="RktSym">mimicked-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acons-recall))" x-target-lift="Figure"></a>Figure&nbsp;189: </span>An implementation of lists in BSL</span></p></blockquote></div></p><p><a href="part_six.html#%28counter._%28figure._fig~3acons-recall%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">189</span></a> recalls the basic idea. Stop! Can you define
<span class="RktSym">our-rest</span> now?</p><p><div class="SIntrapara">The key insight is that we can add a third field to the structure type
definition of <span class="RktSym">pair</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-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">cpair</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">count</span><span class="hspace">&nbsp;</span><span class="RktSym">left</span><span class="hspace">&nbsp;</span><span class="RktSym">right</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A [</span><a name="(tech._mylist)"></a><span style="font-style: italic">MyList</span><span class="RktCmt"> X] is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-cpair</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">tech</span><span class="stt"> </span><span class="RktVal">"N"</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">X</span><span class="stt"> </span><span class="RktPn">[</span><a href="part_six.html#%28tech._mylist%29" class="techoutside" data-pltdoc="x"><span class="techinside">MyList</span></a><span class="stt"> </span><span class="RktSym">X</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> the </span><span class="RktSym">count</span><span class="RktCmt"> field is the number of </span><span class="RktSym">cpair</span><span class="RktCmt">s</span></td></tr></table></blockquote></div><div class="SIntrapara">As the accumulator statement says, the extra field is used to keep track
of the number of <span class="RktSym">cpair</span> instances used to create the list. That
is, it remembers a fact about the construction of the list. We
call this kind of structure field a <span style="font-style: italic">data accumulator</span>.</div></p><p><div class="SIntrapara">Adding a field to the major list constructor does not come for free. To
begin with, it requires a change to the checked version of the
constructor, the one that is actually available to programs: <a name="(idx._(gentag._753))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">data definitions, via a constructor-function </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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-cpair</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">cpair?</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-cpair</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">cpair-count</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"our-cons: ..."</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If the extended list is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, <span class="RktSym">count</span> is populated with
<span class="RktVal">1</span>; otherwise, the function computes the length from the given
<span class="RktSym">cpair</span>.</div></p><p><div class="SIntrapara">Now the function definition for <span class="RktSym">our-length</span> is obvious: <a name="(idx._(gentag._754))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -&gt; </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">&nbsp;</span><span class="RktCmt">how many items does </span><span class="RktSym">l</span><span class="RktCmt"> contain</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">our-length</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">cpair?</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">cpair-count</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"my-length: ..."</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The function consumes any kind of value. For <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> and instances of
<span class="RktSym">cpair</span>, it produces natural numbers; otherwise it signals an
error.</div></p><p>The second problem with the addition of a <span class="RktSym">count</span> field concerns
performance. Indeed, there are two concerns. On the one hand, every single
list construction comes with an extra field now, meaning a 33% increase in
memory consumption. On the other hand, the addition of the field decreases
how fast <span class="RktSym">our-cons</span> constructs a list. In addition to the check
that the extended list is either <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> or an instance of a <span class="RktSym">cpair</span>,
the constructor now computes the size of the list. Although this
computation consumes a constant amount of time, it is imposed on every
single use of <span class="RktSym">our-cons</span>&#8212;<wbr></wbr>and just think how many times this book
uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and does not ever compute how long the resulting list
is!</p><p><a name="(counter._(exercise._ex~3aconstant-time-length))"></a><span style="font-weight: bold">Exercise</span>&nbsp;518. Argue that <span class="RktSym">our-cons</span> takes a
constant amount of time to compute its result, regardless of the size of
its input. <a href="part_six.html#%28counter._%28exercise._ex~3aconstant-time-length%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aextra-cost-cons))"></a><span style="font-weight: bold">Exercise</span>&nbsp;519. Is it acceptable to impose the extra cost
on <span class="RktSym"><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> for all programs to turn <span class="RktSym">length</span> into a
constant-time function? <a href="part_six.html#%28counter._%28exercise._ex~3aextra-cost-cons%29%29" class="ex-end" data-pltdoc="x"></a></p><p>While the addition of a <span class="RktSym">count</span> field to lists is questionable,
sometimes data accumulators play a crucial role in finding a solution. The
next example is about adding so-called <span style="font-style: italic">artificial intelligence</span>
to a board-game-playing program, and its data accumulator is an absolute
necessity.</p><p><div class="SIntrapara">As you play board games or solve puzzles, you tend to think about your
possible moves at every stage. As you get better, you may even imagine the
possibilities after this first step. The result is a so-called
<span style="font-style: italic">game tree</span>, which is a (part of the) tree of all possible moves
that the rules allow. Let&rsquo;s start with a problem:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Your manager tells you the following story.</p><p>&ldquo;Once upon a time, three cannibals were guiding three missionaries through a
jungle. They were on their way to the nearest mission station. After some
time, they arrived at a wide river, filled with deadly snakes and
fish. There was no way to cross the river without a boat. Fortunately,
they found a rowboat with two oars after a short search. Unfortunately,
the boat was too small to carry all of them. It could barely carry two
people at a time. Worse, because of the river&rsquo;s width someone had to
row the boat back.</p><p>&ldquo;Since the missionaries could not trust the cannibals, they had to figure out
a plan to get all six of them safely across the river. The problem was
that these cannibals would kill and eat missionaries as soon as there were
more cannibals than missionaries in some place. Our
missionaries had to devise a plan that guaranteed that there were
never any missionaries in the minority on either side of the river. The
cannibals, however, could be trusted to cooperate otherwise. Specifically,
they would not abandon any potential food, just as the missionaries
would not abandon any potential converts.&rdquo;</p><p>While your manager doesn&rsquo;t assign any specific design task, he wants to
explore whether the company can design (and sell) programs that solve such
puzzles.</p></blockquote></div><div class="SIntrapara">While puzzles aren&rsquo;t board games, the program illustrates the idea of game
trees in the most straightforward manner possible.</div></p><p><div class="SIntrapara">In principle, it is quite straightforward to solve such puzzles by
hand. Here is the rough idea. Pick a graphical representation of the
problem states. Ours consists of a three-part box: the left one represents
the missionaries and the cannibals; the middle combines the
river and the boat; and the third part is the right-hand side of the
river. Take a look at the following representation of the initial state:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_294.png" alt="image" width="114.24000000000001" height="49.56"/></p></blockquote></div><div class="SIntrapara">Black circles denote missionaries, white circles cannibals. All of them are
on the left-hand river bank. The boat is also on the left side. Nobody is
on the right. Here are two more states:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_295.png" alt="image" width="114.24000000000001" height="49.56"/>
<span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_296.png" alt="image" width="114.24000000000001" height="49.56"/></p></blockquote></div><div class="SIntrapara">The first one is the final state, where all people and the boat are on the
right bank of the river. The second one depicts some intermediate state
where two people are on the left with the boat and four people are on the
right.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_297.png" alt="image" width="530.72" height="353.8"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3amc-transition))" x-target-lift="Figure"></a>Figure&nbsp;190: </span>Creating a game tree</span></p></blockquote><p>Now that you have a way to write down the state of the puzzle, you can
think about the possibilities at each stage. Doing so yields a tree of
possible moves. <a href="part_six.html#%28counter._%28figure._fig~3amc-transition%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">190</span></a> sketches the first two and
a half layers in such a tree. The left-most state is the initial
one. Because the boat can transport at most two people and must be rowed
by at least one, you have five possibilities to explore: one cannibal rows
across; two cannibals row across; one missionary and one cannibal go; one
missionary crosses; or two missionaries do. These possibilities are
represented with five arrows going from the initial state to five
intermediate states.</p><p>For each of these five intermediate states, you can play the same game
again. In <a href="part_six.html#%28counter._%28figure._fig~3amc-transition%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">190</span></a> you see how the game continues
for the middle (third) one of the new states. Because there are only two
people on the right river bank, you see three possibilities: a cannibal
goes back, a missionary goes back, or both do. Hence three arrows connect
the middle state to the three states on the right side of the tree. If
you keep drawing this tree of possibilities in a systematic manner, you
eventually discover the final state.</p><p>A second look at <a href="part_six.html#%28counter._%28figure._fig~3amc-transition%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">190</span></a> reveals two problems with
this naive approach to generating the tree of possibilities. The first one
is the dashed arrow that connects the middle state on the right to the
initial state. It indicates that rowing back the two people from the right
to the left gets the puzzle back to its initial state, meaning you&rsquo;re
starting over, which is obviously undesirable. The second problem concerns
those states with a star in the top-right corner. In both cases, there are
more white-circle cannibals than black-circle missionaries on the left
river bank, meaning the cannibals would eat the missionaries. Again, the
goal is to avoid such states, making these moves undesirable.</p><p><div class="SIntrapara">One way to turn this puzzle into a program is to design a function that
determines whether some final state&#8212;<wbr></wbr>here <span style="font-weight: bold">the</span> final state&#8212;<wbr></wbr>is
reachable from some given state. Here is an appropriate function
definition: <a name="(idx._(gentag._755))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a><span class="RktCmt"> -&gt; </span><a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is the final state reachable from </span><span class="RktSym">state0</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">generative</span><span class="RktCmt"> creates a tree of possible boat rides </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">termination ???</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">solve</span><span class="hspace">&nbsp;</span><span class="RktSym">initial-puzzle</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">final-puzzle</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">solve</span><span class="hspace">&nbsp;</span><span class="RktSym">state0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</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_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a><span class="RktCmt">] -&gt; </span><a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">generative</span><span class="RktCmt"> generates the successors of </span><span class="RktSym">los</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">solve*</span><span class="hspace">&nbsp;</span><span class="RktSym">los</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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._ormap%29%29" class="RktValLink" data-pltdoc="x">ormap</a></span><span class="hspace">&nbsp;</span><span class="RktSym">final?</span><span class="hspace">&nbsp;</span><span class="RktSym">los</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span><span class="hspace">&nbsp;</span><span class="RktSym">final?</span><span class="hspace">&nbsp;</span><span class="RktSym">los</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">solve*</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">create-next-states</span><span class="hspace">&nbsp;</span><span class="RktSym">los</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">solve*</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktSym">state0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The auxiliary function uses generative recursion, generating all new
possibilities given a list of possibilities. If one of the given
possibilities is a final state, the function returns it.</div></p><p>Clearly, <span class="RktSym">solve</span> is quite generic. As long as you define a
collection of <a name="(tech._puzzlestate)"></a><span style="font-style: italic">PuzzleState</span>s, a function for recognizing final
states, and a function for creating all &ldquo;successor&rdquo; states,
<span class="RktSym">solve</span> can work on your puzzle.</p><p><a name="(counter._(exercise._ex~3amc-terminates))"></a><span style="font-weight: bold">Exercise</span>&nbsp;520. The <span class="RktSym">solve*</span> function generates all
states reachable with <span style="font-style: italic">n</span> boat trips before it looks at states that
require <span style="font-style: italic">n + </span>1<span style="font-style: italic"></span> boat trips, even if some of those boat trips return
to previously encountered states. Because of this systematic way of
traversing the tree, <span class="RktSym">solve*</span> cannot go into an infinite loop. Why?
<span style="font-weight: bold">Terminology</span> This way of searching a tree or a graph is dubbed
<span style="font-style: italic">breadth-first search</span>. <a href="part_six.html#%28counter._%28exercise._ex~3amc-terminates%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3amc-state))"></a><span style="font-weight: bold">Exercise</span>&nbsp;521. Develop a representation for the states of
the missionary-and-cannibal puzzle. Like the graphical representation, a
data representation must record the number of missionaries and cannibals on
each side of the river plus the location of the boat.</p><p>The description of <a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a> calls for a new structure
type. Represent the above initial, intermediate, and final states in your
representation.</p><p>Design the function <span class="RktSym">final?</span>, which detects whether in a given state
all people are on the right river bank.</p><p>Design the function <span class="RktSym">render-mc</span>, which maps a state of the
missionary-and-cannibal puzzle to an image. <a href="part_six.html#%28counter._%28exercise._ex~3amc-state%29%29" class="ex-end" data-pltdoc="x"></a></p><p>The problem is that returning the final state says nothing about how the
player can get from the initial state to the final one. In other words,
<span class="RktSym">create-next-states</span> forgets how it gets to the returned states
from the given ones. And this situation clearly calls for an accumulator,
but at the same time, the accumulated knowledge is best associated with
every individual <a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a>, not <span class="RktSym">solve*</span> or any other
function.</p><p><a name="(counter._(exercise._ex~3amc-accu-state))"></a><span style="font-weight: bold">Exercise</span>&nbsp;522. Modify the representation from
<a href="part_six.html#%28counter._%28exercise._ex~3amc-state%29%29" data-pltdoc="x">exercise&nbsp;521</a> so that a state records the sequence of states
traversed to get there. Use a list of states.</p><p>Articulate and write down an accumulator statement with the data definition
that explains the additional field.</p><p>Modify <span class="RktSym">final?</span> or <span class="RktSym">render-mc</span> for this representation as needed. <a href="part_six.html#%28counter._%28exercise._ex~3amc-accu-state%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3amc-next-state))"></a><span style="font-weight: bold">Exercise</span>&nbsp;523. Design the <span class="RktSym">create-next-states</span>
function. It consumes lists of missionary-and-cannibal states and
generates the list of all those states that a boat ride can reach.</p><p>Ignore the accumulator in the first draft of <span class="RktSym">create-next-states</span>,
but make sure that the function does not generate states where the
cannibals can eat the missionaries.</p><p>For the second design, update the accumulator field in the state structures
and use it to rule out states that have been encountered on the way to the
current state. <a href="part_six.html#%28counter._%28exercise._ex~3amc-next-state%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3amc-solve))"></a><span style="font-weight: bold">Exercise</span>&nbsp;524. Exploit the accumulator-oriented data
representation to modify <span class="RktSym">solve</span>. The revised function produces the
list of states that lead from the initial <a href="part_six.html#%28tech._puzzlestate%29" class="techoutside" data-pltdoc="x"><span class="techinside">PuzzleState</span></a> to the final one.</p><p>Also consider creating a movie from this list, using <span class="RktSym">render-mc</span> to
generate the images. Use <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._%28%28lib._2htdp%2Funiverse..rkt%29._run-movie%29%29" class="RktValLink" data-pltdoc="x">run-movie</a></span> to display the movie. <a href="part_six.html#%28counter._%28exercise._ex~3amc-solve%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>33.3<tt>&nbsp;</tt><a name="(part._sec~3afractal-acc)"></a>Accumulators as Results</h4><p><div class="SIntrapara">Take another look at <a href="part_five.html#%28counter._%28figure._fig~3asiepic%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">156</span></a>. It displays a Sierpinski triangle and a suggestion
how to create it. Specifically, the
images on the right explain one version of the generative idea behind the
process:
</div><div class="SIntrapara"><blockquote><p>The given problem is a triangle. When
the triangle is too small to be subdivided any further, the algorithm does
nothing; otherwise, it finds the midpoints of its three sides and deals
with the three outer triangles recursively.</p></blockquote></div><div class="SIntrapara">In contrast, <a href="part_five.html#%28part._sec~3afractal%29" data-pltdoc="x">Fractals, a First Taste</a> shows how to compose Sierpinski triangles
algebraically, a process that does not correspond to this description.</div></p><p><div class="SIntrapara">Most programmers expect &ldquo;draw&rdquo; to mean the action of adding a
triangle to some canvas. The <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span> function from
<span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/image</span></span> teachpack</span> makes this idea concrete. The function consumes an image
<span class="RktSym">s</span> and the coordinates of two points and adds a line through these
two points to <span class="RktSym">s</span>. It is easy to generalize from <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span>
to <span class="RktSym">add-triangle</span> and from there to <span class="RktSym">add-sierpinski</span>:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design the <span class="RktSym">add-sierpinski</span> function. It consumes an
image and three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s describing a triangle. It uses the latter to
add a Sierpinski triangle to this image.</p></blockquote></div><div class="SIntrapara">Note how this problem implicitly refers to the above process
description of how to draw a Sierpinski triangle. In other words, we are
confronted with a classical generative-recursive problem, and we can start
with the classic template of generative recursion and the four central
design questions:
</div><div class="SIntrapara"><ul><li><p>The problem is trivial if the triangle is too small to be
subdivided.</p></li><li><p>In the trivial case, the function returns the given image.</p></li><li><p>Otherwise the midpoints of the sides of the given triangle are
determined to add another triangle. Each &ldquo;outer&rdquo; triangle is then
processed recursively.</p></li><li><p>Each of these recursive steps produces an image. The remaining
question is how to combine these images.</p></li></ul></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._756))"></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">&nbsp;</span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">generative</span><span class="RktCmt"> adds the triangle (</span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt">) to </span><span class="RktSym">scene0</span><span class="RktCmt">, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">subdivides it into three triangles by taking the </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">midpoints of its sides; stop if (</span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt">) is too small</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">too-small?</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">scene1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-triangle</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene2</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene3</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene4</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&#8212;<wbr></wbr></span><span class="RktCmt">IN</span><span class="RktCmt">&#8212;<wbr></wbr></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene1</span><span class="hspace">&nbsp;</span><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">&nbsp;</span><span class="RktSym">scene2</span><span class="hspace">&nbsp;</span><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">&nbsp;</span><span class="RktSym">scene3</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aaccu-result-gen-temp))" x-target-lift="Figure"></a>Figure&nbsp;191: </span>Accumulators as results of generative recursions, a skeleton</span></p></blockquote></div></p><p><a href="part_six.html#%28counter._%28figure._fig~3aaccu-result-gen-temp%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">191</span></a> shows the result of translating
these answers into a skeletal definition. Since each midpoint is used
twice, the skeleton uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to formulate the
generative step in ISL+. 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 introduces the
three new midpoints plus three recursive applications of
<span class="RktSym">add-sierpinski</span>. The dots in its body suggest a combination of the
scenes.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asierpinski-aux))"></a><span style="font-weight: bold">Exercise</span>&nbsp;525. Tackle the wish list that the
skeleton implies: <a name="(idx._(gentag._757))"></a> <a name="(idx._(gentag._758))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">adds the black triangle </span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt"> to </span><span class="RktSym">scene</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-triangle</span><span class="hspace">&nbsp;</span><span class="RktSym">scene</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">scene</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is the triangle </span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt"> too small to be divided</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">too-small?</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -&gt; </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">&nbsp;</span><span class="RktCmt">determines the midpoint between </span><span class="RktSym">a</span><span class="RktCmt"> and </span><span class="RktSym">b</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Design the three functions. <a name="(idx._(gentag._759))"></a></div></p><p><div class="SIntrapara"><span style="font-weight: bold">Domain Knowledge</span> (1) For the <span class="RktSym">too-small?</span> function it suffices to
measure the distance between two points and to check whether it is below
some chosen threshold, say, <span class="RktVal">10</span>. The distance between
<span style="font-style: italic"></span>(<span style="font-style: italic">x</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic">,y</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> and <span style="font-style: italic"></span>(<span style="font-style: italic">x</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">,y</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 style="font-style: italic"></span> is
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><blockquote class="SCentered"><p><img src="pict_298.png" alt="image" width="136" height="15"/></p></blockquote></blockquote></div><div class="SIntrapara">that is, the distance of <span style="font-style: italic"></span>(<span style="font-style: italic">x</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"> - x</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">,y</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"> - y</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 style="font-style: italic"></span> to the origin.</div></p><p><div class="SIntrapara">The midpoint between points <span style="font-style: italic"></span>(<span style="font-style: italic">x</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic">,y</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> and <span style="font-style: italic"></span>(<span style="font-style: italic">x</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">,y</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 style="font-style: italic"></span> has as
coordinates the midpoints between the respective x and y coordinates:
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><blockquote class="SCentered"><p><img src="pict_299.png" alt="image" width="153" height="15"/>
<a href="part_six.html#%28counter._%28exercise._ex~3asierpinski-aux%29%29" class="ex-end" data-pltdoc="x"></a></p></blockquote></blockquote></div></p><p>Now that we have all the auxiliary functions, it is time to return to the problem
of combining the three images that are created by the recursive calls. One obvious
guess is to use the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._overlay%29%29" class="RktValLink" data-pltdoc="x">overlay</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._underlay%29%29" class="RktValLink" data-pltdoc="x">underlay</a></span> function, but an evaluation
in the interactions area of DrRacket shows that the functions hide the underlying
triangles.</p><p><div class="SIntrapara">Specifically, imagine that the three recursive calls produce the following empty
scenes, enriched with a single triangle in appropriate locations:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktSym">scene1</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_300.png" alt="image" width="57" height="37"/></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktSym">scene2</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_301.png" alt="image" width="57" height="37"/></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktSym">scene3</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_302.png" alt="image" width="57" height="37"/></p></td></tr></table></blockquote></div><div class="SIntrapara">A combination should look like this figure:
</div><div class="SIntrapara"><blockquote><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_303.png" alt="image" width="56" height="36"/></p></blockquote></div><div class="SIntrapara">But, combining these shapes with <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._overlay%29%29" class="RktValLink" data-pltdoc="x">overlay</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._underlay%29%29" class="RktValLink" data-pltdoc="x">underlay</a></span>
does not yield this desired shape:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </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._overlay%29%29" class="RktValLink" data-pltdoc="x">overlay</a></span><span class="hspace">&nbsp;</span><span class="RktSym">scene1</span><span class="hspace">&nbsp;</span><span class="RktSym">scene2</span><span class="hspace">&nbsp;</span><span class="RktSym">scene3</span><span class="RktPn">)</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_304.png" alt="image" width="57" height="37"/></p></td></tr><tr><td><span class="stt">&gt; </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._underlay%29%29" class="RktValLink" data-pltdoc="x">underlay</a></span><span class="hspace">&nbsp;</span><span class="RktSym">scene1</span><span class="hspace">&nbsp;</span><span class="RktSym">scene2</span><span class="hspace">&nbsp;</span><span class="RktSym">scene3</span><span class="RktPn">)</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_305.png" alt="image" width="57" height="37"/></p></td></tr></table></blockquote></div><div class="SIntrapara">Indeed, the image teachpack of ISL+ does not support a function that
combines these scenes in an appropriate manner.</div></p><p><div class="SIntrapara">Let&rsquo;s take a second look at these interactions. If <span class="RktSym">scene1</span> is the
result of adding the upper triangle to the given scene and <span class="RktSym">scene2</span>
is the result of adding a triangle on the lower left, perhaps the second
recursive call should add triangles to the result of the first call. Doing
so would yield
</div><div class="SIntrapara"><blockquote><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_306.png" alt="image" width="56" height="36"/></p></blockquote></div><div class="SIntrapara">and handing over this scene to the third recursive call produces exactly
what is wanted:
</div><div class="SIntrapara"><blockquote><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_307.png" alt="image" width="56" height="36"/></p></blockquote></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._760))"></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">&nbsp;</span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">generative</span><span class="RktCmt"> adds the triangle (</span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt">) to </span><span class="RktSym">scene0</span><span class="RktCmt">, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">subdivides it into three triangles by taking the </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">midpoints of its sides; stop if (</span><span class="RktSym">a</span><span class="RktCmt">, </span><span class="RktSym">b</span><span class="RktCmt">, </span><span class="RktSym">c</span><span class="RktCmt">) is too small</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">accumulator</span><span class="RktCmt"> the function accumulates the triangles of </span><span class="RktSym">scene0</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">too-small?</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span><span class="RktSym">scene1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-triangle</span><span class="hspace">&nbsp;</span><span class="RktSym">scene0</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">mid-point</span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene2</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktSym">scene1</span></span><span class="hspace">&nbsp;</span><span class="RktSym">a</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><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">&nbsp;</span><span class="RktSym">scene3</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktSym">scene2</span></span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-a-b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&#8212;<wbr></wbr></span><span class="RktCmt">IN</span><span class="RktCmt">&#8212;<wbr></wbr></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktSym">scene3</span></span><span class="hspace">&nbsp;</span><span class="RktSym">c</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-c-a</span><span class="hspace">&nbsp;</span><span class="RktSym">mid-b-c</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aadd-sierpinski))" x-target-lift="Figure"></a>Figure&nbsp;192: </span>Accumulators as results of generative recursion, the function</span></p></blockquote></div></p><p><a href="part_six.html#%28counter._%28figure._fig~3aadd-sierpinski%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">192</span></a> shows the reformulation based on this insight.
The three highlights pinpoint the key design idea. All concern the case
when the triangle is sufficiently large and it is added to the given scene.
Once its sides are subdivided, the first outer triangle is recursively
processed using <span class="RktSym">scene1</span>, the result of adding the given
triangle. Similarly, the result of this first recursion, dubbed
<span class="RktSym">scene2</span>, is used for the second recursion, which is about
processing the second triangle. Finally, <span class="RktSym">scene3</span> flows into the
third recursive call. In sum, the novelty is that the accumulator is
simultaneously an argument, a tool for collecting knowledge, and the
result of the function.</p><p><div class="SIntrapara">To explore <span class="RktSym">add-sierpinski</span> it is best to start from an equilateral
triangle and an image that leaves a sufficiently large border. Here are
definitions that meet these two criteria:
</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">&nbsp;</span><span class="RktSym">MT</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace">&nbsp;</span><span class="RktVal">400</span><span class="hspace">&nbsp;</span><span class="RktVal">400</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">&nbsp;</span><span class="RktSym">A</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">200</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">50</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">&nbsp;</span><span class="RktSym">B</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;&nbsp;</span><span class="RktVal">27</span><span class="hspace">&nbsp;</span><span class="RktVal">350</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">&nbsp;</span><span class="RktSym">C</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">373</span><span class="hspace">&nbsp;</span><span class="RktVal">350</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">add-sierpinski</span><span class="hspace">&nbsp;</span><span class="RktSym">MT</span><span class="hspace">&nbsp;</span><span class="RktSym">A</span><span class="hspace">&nbsp;</span><span class="RktSym">B</span><span class="hspace">&nbsp;</span><span class="RktSym">C</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Check what kind of Sierpinski fractal this code fragment
delivers. Experiment with the definitions from <a href="part_six.html#%28counter._%28exercise._ex~3asierpinski-aux%29%29" data-pltdoc="x">exercise&nbsp;525</a> to
create sparser and denser Sierpinski triangles than the first one.</div></p><p><a name="(counter._(exercise._ex~3asierpinski-start))"></a><span style="font-weight: bold">Exercise</span>&nbsp;526. To compute the endpoints of an equilateral
Sierpinski triangle, draw a circle and pick three points on the circle that
are 120 degrees apart, for example, 120, 240, and 360.</p><p><div class="SIntrapara">Design the function <span class="RktSym">circle-pt</span>: <a name="(idx._(gentag._761))"></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">&nbsp;</span><span class="RktSym">CENTER</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">200</span><span class="hspace">&nbsp;</span><span class="RktVal">200</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">&nbsp;</span><span class="RktSym">RADIUS</span><span class="hspace">&nbsp;</span><span class="RktVal">200</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">the radius in pixels </span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">determines the point on the circle with </span><span class="RktSym">CENTER</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">and </span><span class="RktSym">RADIUS</span><span class="RktCmt"> whose angle is </span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">examples</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">what are the x and y coordinates of the desired </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">point, when given: 120/360, 240/360, 360/360</span></td></tr><tr><td><span class="hspace">&nbsp;</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">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">circle-pt</span><span class="hspace">&nbsp;</span><span class="RktSym">factor</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><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">&nbsp;</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><span style="font-weight: bold">Domain Knowledge</span> This design problem calls on knowledge from
mathematics. One way to view the problem is as a conversion of a complex
number from the polar-coordinate representation to the <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>
representation. Read up on <span class="RktSym"><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-polar%29%29" class="RktValLink" data-pltdoc="x">make-polar</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._real-part%29%29" class="RktValLink" data-pltdoc="x">real-part</a></span>, and
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._imag-part%29%29" class="RktValLink" data-pltdoc="x">imag-part</a></span> in ISL+. Another way is to use trigonometry,
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sin%29%29" class="RktValLink" data-pltdoc="x">sin</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cos%29%29" class="RktValLink" data-pltdoc="x">cos</a></span>, to determine the coordinates. If you
choose this route, recall that these trigonometry functions
compute the sine and cosine in terms of radians, not degrees. Also keep
in mind that on-screen positions grow downward, not upward. <a href="part_six.html#%28counter._%28exercise._ex~3asierpinski-start%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3atree-generation))"></a><span style="font-weight: bold">Exercise</span>&nbsp;527. Take a look at the following two images:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_308.png" alt="image" width="138.0" height="138.0"/><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_309.png" alt="image" width="138.0" height="138.0"/></p></blockquote></div><div class="SIntrapara">They demonstrate how to generate a fractal Savannah tree in the same way that
<a href="part_five.html#%28counter._%28figure._fig~3asiepic%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">156</span></a> shows how to draw a Sierpinski triangle. The
image on the left shows what a fractal Savannah tree looks like. The right
one explains the generative construction step.</div></p><p>Design the function <span class="RktSym">add-savannah</span>. The function consumes an image
and four numbers: (1) the x-coordinate of a line&rsquo;s base point, (2)
the y-coordinate of a line&rsquo;s base point, (3) the length of the line,
and (4) the angle of the line. It adds a fractal Savannah tree to the given
image.</p><p>Unless the line is too short, the function adds the specified line to the
image. It then divides the line into three segments. It recursively uses
the two intermediate points as the new starting points for two lines. The
lengths and the angles of the two branches change in a fixed manner, but
independently of each other. Use constants to define these changes and work
with them until you like your tree well enough.</p><p><span style="font-weight: bold">Hint</span> Experiment with shortening each left branch by at least one
third and rotating it left by at least <span class="RktVal">0.15</span> degrees. For each right
branch, shorten it by at least 20% and rotate it by <span class="RktVal">0.2</span> degrees in
the opposite direction. <a href="part_six.html#%28counter._%28exercise._ex~3atree-generation%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3abezier))"></a><span style="font-weight: bold">Exercise</span>&nbsp;528. Graphics programmers often need to connect two
points with a smooth curve where &ldquo;smooth&rdquo; is relative to some
perspective.<span class="refelem"><span class="refcolumn"><span class="refcontent">G&#233;raldine Morin suggested this exercise.</span></span></span>
Here are two sketches:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_310.png" alt="image" width="138.0" height="138.0"/><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_311.png" alt="image" width="138.0" height="138.0"/></p></blockquote></div><div class="SIntrapara">The left one shows a smooth curve, connecting points <span style="font-style: italic">A</span> and
<span style="font-style: italic">C</span>; the right one supplies the perspective point, <span style="font-style: italic">B</span>, and the
angle of an observer.</div></p><p><div class="SIntrapara">One method for drawing such curves is due to B&#233;zier. It is a prime example
of generative recursion, and the following sequence explains the
<span style="font-style: italic">eureka!</span> behind the algorithm:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_312.png" alt="image" width="138.0" height="138.0"/><span class="hspace">&nbsp;&nbsp;</span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_313.png" alt="image" width="138.0" height="138.0"/><span class="hspace">&nbsp;&nbsp;</span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_314.png" alt="image" width="138.0" height="138.0"/></p></blockquote></div><div class="SIntrapara">Consider the image on the left. It reminds you that the three given points determine a
triangle and that the connection from <span style="font-style: italic">A</span> to <span style="font-style: italic">C</span> is the focal
point of the algorithm. The goal is to pull the line from <span style="font-style: italic">A</span> to
<span style="font-style: italic">C</span> toward <span style="font-style: italic">B</span> so that it turns into a smooth curve.</div></p><p>Now turn to the image in the middle. It explains the essential idea of the
generative step. The algorithm determines the midpoint on the two observer
lines, <span style="font-style: italic">A-B</span> and <span style="font-style: italic">B-C</span>, as well as their midpoint, <span style="font-style: italic">A-B-C</span>.</p><p>Finally, the right-most image shows how these three new points generate
two distinct recursive calls: one deals with the new triangle on the left
and the other one with the triangle on the right. More precisely,
<span style="font-style: italic">A-B</span> and <span style="font-style: italic">B-C</span> become the new observer points and the lines
from <span style="font-style: italic">A</span> to <span style="font-style: italic">A-B-C</span> and from <span style="font-style: italic">C</span> to <span style="font-style: italic">A-B-C</span> become the
foci of the two recursive calls.</p><p>When the triangle is small enough, we have a trivially solvable case. The
algorithm just draws the triangle, and it appears as a point on the given
image. As you implement this algorithm, you need to experiment with
the notion of &ldquo;small enough&rdquo; to make the curve look smooth. <a href="part_six.html#%28counter._%28exercise._ex~3abezier%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>34<tt>&nbsp;</tt><a name="(part._ch~3asummary6)"></a>Summary</h3><p><div class="SIntrapara">This last part is about designing with accumulators, a mechanism for
collecting knowledge during a data structure traversal. Adding an
accumulator can fix performance flaws and eliminate <a name="(idx._(gentag._762))"></a>termination problems.
Your takeaway from this part are two and a half design lessons:
</div><div class="SIntrapara"><ol><li><p>The first step is to recognize the need for introducing an
accumulator. Traversals &ldquo;forget&rdquo; pieces of the argument when
they step from one piece to the next. If you discover that such knowledge could simplify the
function&rsquo;s design, consider introducing an accumulator. The first step is
to switch to the <span style="font-weight: bold">accumulator template</span>.</p></li><li><p>The key step is to formulate an <a name="(idx._(gentag._763))"></a>accumulator statement. The latter
must express <span style="font-weight: bold">what knowledge</span> the accumulator gathers <span style="font-weight: bold">as what
kind of data</span>. In most cases, the accumulator statement describes the
difference between the original argument and the current one.</p></li><li><p>The third step, a minor one, is to deduce from the accumulator
statement (a) what the initial accumulator value is, (b) how to maintain it
during traversal steps, and (c) how to exploit its knowledge.</p></li></ol></div></p><p>The idea of accumulating knowledge is ubiquitous, and it appears in many
different forms and shapes. It is widely used in so-called functional
languages like ISL+. Programmers using imperative languages encounter
accumulators in a different way, mostly via assignment statements in primitive
looping constructs because the latter cannot return values. Designing such
imperative accumulator programs proceeds just like the design of accumulator
functions here, but the details are beyond the scope of this first book on
systematic program design.</p><div class="navsetbottom"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;<span class="tocsettoggle">&nbsp;&nbsp;<a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright">&nbsp;&nbsp;<a href="i5-6.html" title="backward to &quot;Intermezzo 5: The Cost of Computation&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;How to Design Programs, Second Edition&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="part_epilogue.html" title="forward to &quot;Epilogue: Moving On&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>