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

1934 lines
1 MiB
HTML
Raw Normal View History

2022-08-15 11:06:56 +02:00
<!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>IV&nbsp;Intertwined Data</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="figure.css" title="default"/><link rel="stylesheet" type="text/css" href="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-racket.css" title="default"/><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="tocviewselflink" 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="tocviewlink" data-pltdoc="x">Accumulators</a></td></tr><tr><td align="right"></td><td><a href="part_epilogue.html" class="tocviewlink" data-pltdoc="x">Epilogue:<span class="mywbr"> &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>IV&nbsp;</td><td><a href="part_four.html" class="tocviewselflink" data-pltdoc="x">Intertwined Data</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">19&nbsp;</td><td><a href="part_four.html#%28part._ch~3apoetry-sexp%29" class="tocviewlink" data-pltdoc="x">The Poetry of S-<wbr>
quite unusual. These data definitions refer to themselves, and in all
likelihood they are the first such definitions you have ever
encountered. As it turns out, many classes of data require even more
complex data definitions than these two. Common generalizations involve
many self-references in one data definition or a bunch of data definitions
that refer to each other. These forms of data have become ubiquitous, and
it is therefore critical for a programmer to learn to cope with <span style="font-weight: bold">any</span>
collection of data definitions. And that&rsquo;s what the design recipe is all
about.</p><p>This part starts with a generalization of the design recipe so that it
works for all forms of <a name="(idx._(gentag._494))"></a>structural data definitions. Next, it introduces
the concept of <a name="(idx._(gentag._495))"></a>iterative refinement from <a href="part_two.html#%28part._ch~3aproj-lists%29" data-pltdoc="x">Projects: Lists</a> on a
rigorous basis because complex data definitions are not developed in one
fell swoop but in several stages. Indeed, the use of iterative refinement
is one of the reasons why all programmers are little scientists and why
our discipline uses the word &ldquo;science&rdquo; in its American name. Two last
chapters illustrate these ideas: one explains how to design an interpreter
for BSL and another is about processing XML, a data exchange language
for the web. The last chapter expands the design recipe one more time,
reworking it for functions that process two complex arguments at the same
time.</p><h3>19<tt>&nbsp;</tt><a name="(part._ch~3apoetry-sexp)"></a>The Poetry of S-expressions</h3><p>Programming resembles poetry. Like poets, programmers practice their skill
on seemingly pointless ideas. They revise and edit all the time, as the
preceding chapter explains. This chapter introduces increasingly complex
forms of data&#8212;<wbr></wbr>seemingly without a real-world purpose. Even when we
provide a motivational background, the chosen kinds of data are pure to an
extreme, and it is unlikely that you will ever encounter them again.</p><p>Nevertheless, this chapter shows the full power of the design recipe and
introduces you to the kinds of data that real-world programs cope with.
To connect this material with what you will encounter in your life as a
programmer, we label each section with appropriate names: trees, forests,
XML. The last one is a bit misleading because it is really about
S-expressions; the connection between S-expressions and XML is clarified
in <a href="part_four.html#%28part._ch~3amoney-sexp%29" data-pltdoc="x">Project: The Commerce of XML</a>, which, in contrast to this chapter, comes much
closer to real-world uses of complex forms of data.</p><h4>19.1<tt>&nbsp;</tt><a name="(part._sec~3abtrees)"></a>Trees</h4><p>All of us have a family tree. One way to draw a family tree is to add an
element every time a child is born and to connect the elements of the
father and mother. For those people whose parents are unknown, there is no
connection to draw. The result is an <span style="font-style: italic">ancestor family tree</span>
because, given any person, the tree points to all of the person&rsquo;s known
ancestors.</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_140.png" alt="image" width="283.2" height="170.78"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3afamily-tree))" x-target-lift="Figure"></a>Figure&nbsp;111: </span>A family tree</span></p></blockquote><p><a href="part_four.html#%28counter._%28figure._fig~3afamily-tree%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">111</span></a> displays a three-tier family tree. Gustav is
the child of Eva and Fred, while Eva is the child of Carl and Bettina. In
addition to people&rsquo;s names and family relationships, the tree also records
years of birth and eye colors. Based on this sketch, you can easily imagine
a family tree reaching back many generations and one that records other
kinds of information.</p><p><div class="SIntrapara">Once a family tree is large, it makes sense to represent it as data and to
design programs that process this kind of data. Given that a point in a
family tree combines five pieces of information&#8212;<wbr></wbr>the father, the mother,
the name, the birth date, and the eye color&#8212;<wbr></wbr>we should define a structure type:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">child</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">father</span><span class="hspace">&nbsp;</span><span class="RktSym">mother</span><span class="hspace">&nbsp;</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">date</span><span class="hspace">&nbsp;</span><span class="RktSym">eyes</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The structure type definition calls a data definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._child)"></a><span style="font-style: italic">Child</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-child</span><span class="stt"> </span><a href="part_four.html#%28tech._child%29" class="techoutside" data-pltdoc="x"><span class="techinside">Child</span></a><span class="stt"> </span><a href="part_four.html#%28tech._child%29" class="techoutside" data-pltdoc="x"><span class="techinside">Child</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">While this data definition looks straightforward, it is also useless. It
refers to itself, but, because it doesn&rsquo;t have any clauses, there is no way
to create a proper instance <a href="part_four.html#%28tech._child%29" class="techoutside" data-pltdoc="x"><span class="techinside">Child</span></a>. Roughly, we would have to write
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</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="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></p></blockquote></div><div class="SIntrapara">without end. To avoid such pointless data definitions, we demand that a
self-referential data definition have several clauses and that at
least one of them does not refer back to the data definition.</div></p><p><div class="SIntrapara">Let&rsquo;s postpone the data definition for a moment, and experiment instead.
Suppose we are about to add a child to an existing family tree and that we
already have representations for the parents. In that case, we can simply
construct a new <span class="RktSym">child</span> structure. For example, to represent Adam in a
program that already represents Carl and Bettina, it suffices to add the
following <span class="RktSym">child</span> structure:
</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">Adam</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="hspace">&nbsp;</span><span class="RktSym">Bettina</span><span class="hspace">&nbsp;</span><span class="RktVal">"Adam"</span><span class="hspace">&nbsp;</span><span class="RktVal">1950</span><span class="hspace">&nbsp;</span><span class="RktVal">"hazel"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">assuming <span class="RktSym">Carl</span> and <span class="RktSym">Bettina</span> stand for representations of
Adam&rsquo;s parents.</div></p><p><div class="SIntrapara">Then again, a person&rsquo;s parents may be unknown, like Bettina&rsquo;s in the family
tree of <a href="part_four.html#%28counter._%28figure._fig~3afamily-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">111</span></a>. Yet, even then, we must fill the
corresponding parent field(s) in the <span class="RktSym">child</span> representation.
Whatever data we choose, it must signal an absence of information. On
the one hand, we could use <span class="RktVal">#false</span>, <span class="RktVal">"none"</span>, or <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>
from the pool of existing values. On the other hand, we should really say
that the information is missing from a family tree. We can achieve this
objective best with the introduction of a structure type with an
appropriate name:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">no-parent</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Now, to construct a <span class="RktSym">child</span> structure for Bettina, we say
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-no-parent</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">make-no-parent</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="RktVal">"Bettina"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Of course, if only one piece of information is missing, we fill just that
field with this special value.</div></p><p><div class="SIntrapara">Our experimentation suggests two insights. First, we are <span style="font-weight: bold">not</span> looking for a data
definition that describes how to generate instances of <span class="RktSym">child</span>
structures but for a data definition that describes how to represent family
trees. Second, the data definition consists of two clauses, one for the variant
describing unknown family trees and another one for known family trees:
</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">no-parent</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">child</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">father</span><span class="hspace">&nbsp;</span><span class="RktSym">mother</span><span class="hspace">&nbsp;</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">date</span><span class="hspace">&nbsp;</span><span class="RktSym">eyes</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._ft)"></a><span style="font-style: italic">FT</span><span class="RktCmt"> (short for </span><span style="font-style: italic">family 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="RktPn">(</span><span class="RktSym">make-no-parent</span><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">make-child</span><span class="stt"> </span><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="stt"> </span><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since the &ldquo;no parent&rdquo; tree is going to show up a lot in our programs, we
define <span class="RktSym">NP</span> as a short-hand and revise the data definition a bit:
</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">NP</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-no-parent</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><span style="font-style: italic">FT</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="RktSym">NP</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-child</span><span class="stt"> </span><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="stt"> </span><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Following the design recipe from <a href="part_two.html#%28part._ch~3adesign-lists%29" data-pltdoc="x">Designing with Self-Referential Data Definitions</a>, we use the data
definition to create examples of family trees. Specifically, we translate the
family tree in <a href="part_four.html#%28counter._%28figure._fig~3afamily-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">111</span></a> into our data representation. The
information for Carl is easy to translate into data:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Bettina and Fred are represented with similar instances of <span class="RktSym">child</span>. The
case for Adam calls for nested children, one for Carl and one for Bettina:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</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">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Bettina"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</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="RktVal">"Adam"</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">1950</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">"hazel"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since the records for Carl and Bettina are also needed to construct the records
for Dave and Eva, it is better to introduce definitions that name specific
instances of <span class="RktSym">child</span> and to use the variable names elsewhere.
<a href="part_four.html#%28counter._%28figure._fig~3afamily.S%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">112</span></a> illustrates this approach for the complete
data representation of the family tree from <a href="part_four.html#%28counter._%28figure._fig~3afamily-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">111</span></a>. Take
a close look; the tree serves as our running example for the following design
exercise.</div></p><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">Oldest Generation:</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">Carl</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</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">Bettina</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Bettina"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</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">Middle Generation:</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">Adam</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="hspace">&nbsp;</span><span class="RktSym">Bettina</span><span class="hspace">&nbsp;</span><span class="RktVal">"Adam"</span><span class="hspace">&nbsp;</span><span class="RktVal">1950</span><span class="hspace">&nbsp;</span><span class="RktVal">"hazel"</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">Dave</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="hspace">&nbsp;</span><span class="RktSym">Bettina</span><span class="hspace">&nbsp;</span><span class="RktVal">"Dave"</span><span class="hspace">&nbsp;</span><span class="RktVal">1955</span><span class="hspace">&nbsp;</span><span class="RktVal">"black"</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">Eva</span><span clas
the generic organization of such a function. That is, let&rsquo;s work through the
design recipe as much as possible without having a concrete task in mind. We
start with the header material, that is, step 2 of the recipe:
</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_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="RktCmt"> -&gt; ???</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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></table></blockquote></div><div class="SIntrapara">Even though we aren&rsquo;t stating the purpose of the function, we do know
that it consumes a family tree and that this form of data is the main input.
The &ldquo;???&rdquo; in the signature says that we don&rsquo;t know what kind
of data the function produces; the &ldquo;...&rdquo; remind us that we don&rsquo;t know its
purpose.</div></p><p><div class="SIntrapara">The lack of purpose means we cannot make up functional examples. Nevertheless,
we can exploit the organization of the data definition for <span class="RktSym">FT</span> to design
a template. Since it consists of two clauses, the template must consist of a
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression with two clauses:
</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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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="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></p><p><div class="SIntrapara">In case the argument to <span class="RktSym">fun-FT</span> satisfies <span class="RktSym">no-parent?</span>,
the structure contains no additional data, so the first clause is
complete. For the second clause, the input contains five pieces of
data, which we indicate with five selectors in the 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><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="RktCmt"> -&gt; ???</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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;</span><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">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;</span><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">child-name</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermedi
data definition refers to itself, the function is likely to recur and
templates indicate so with suggestive natural recursions. The definition
for <a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a> has two self-references, and the template therefore
needs two such recursions:
</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_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="RktCmt"> -&gt; ???</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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;</span><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">fun-FT</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;</span><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><
for fathers and mothers 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 because the
second clause of the data definition contains corresponding self-references.</div></p><p><div class="SIntrapara">Let&rsquo;s now turn to a concrete example, the <span class="RktSym">blue-eyed-child?</span> function. Its
purpose is to determine whether any <span class="RktSym">child</span> structure in a given
family tree has blue eyes. You may copy, paste, and rename
<span class="RktSym">fun-FT</span> to get its template; we replace &ldquo;???&rdquo; with
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> and add a purpose statement: <a name="(idx._(gentag._496))"></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_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</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">does </span><span class="RktSym">an-ftree</span><span class="RktCmt"> contain a </span><span class="RktSym">child</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">structure with </span><span class="RktVal">"blue"</span><span class="RktCmt"> in the </span><span class="RktSym">eyes</span><span class="RktCmt"> field</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">blue-eyed-child?</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">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;</span><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">blue-eyed-child?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
name with a specific one.</div></p><p><div class="SIntrapara">Checking with our recipe, we realize that we need to backtrack and develop
some examples before we move on to the definition step. If we start with Carl,
the first person in the family tree, we see that Carl&rsquo;s family tree does
not contain a <span class="RktSym">child</span> with a <span class="RktVal">"blue"</span> eye color. Specifically, the
<span class="RktSym">child</span> representing Carl says the eye color is <span class="RktVal">"green"</span>; given
that Carl&rsquo;s ancestor trees are empty, they cannot possibly contain a <span class="RktSym">child</span>
with <span class="RktVal">"blue"</span> eye color:
</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">In contrast, <span class="RktSym">Gustav</span> contains a <span class="RktSym">child</span> for <span class="RktSym">Eva</span> who does have blue eyes:
</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Gustav</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></p></blockquote></div></p><p>Now we are ready to define the actual function. The function distinguishes
between two cases: a <span class="RktSym">no-parent</span> and a <span class="RktSym">child</span>. For the
first case, the answer should be obvious even though we haven&rsquo;t made up
any examples. Since the given family tree does not contain any
<span class="RktSym">child</span> whatsoever, it cannot contain one with <span class="RktVal">"blue"</span> as the
eye color. Hence the result in the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause is
<span class="RktVal">#false</span>.</p><p><div class="SIntrapara">For the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause, the design requires a lot more work.
Again following the design recipe, we first remind ourselves what the
expressions in the template accomplish:
</div><div class="SIntrapara"><ol><li><p><div class="SIntrapara">according to the purpose statement for the function,
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">determines whether some <span class="RktSym">child</span> in the father&rsquo;s <a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a> has
<span class="RktVal">"blue"</span> eyes;</div></p></li><li><p>likewise, <span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span>
determines whether someone in the mother&rsquo;s <a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a> has blue eyes; and</p></li><li><p>the selector expressions <span class="RktPn">(</span><span class="RktSym">child-name</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span>,
<span class="RktPn">(</span><span class="RktSym">child-date</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span>, and <span class="RktPn">(</span><span class="RktSym">child-eyes</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span> extract
the name, birth date, and eye color from the given <span class="RktSym">child</span>
structure, respectively.</p></li></ol></div><div class="SIntrapara">Now we just need to figure out how to combine these expressions.</div></p><p>Clearly, if the <span class="RktSym">child</span> structure contains <span class="RktVal">"blue"</span> in the
<span class="RktSym">eyes</span> field, the function&rsquo;s answer is <span class="RktVal">#true</span>. Next, the
expressions concerning names and birth dates are useless, which leaves us
with the recursive calls. As stated, <span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span> traverses the tree on the father&rsquo;s side,
while the mother&rsquo;s side of the family tree is processed with
<span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span>. If either of these
expressions returns <span class="RktVal">#true</span>, <span class="RktSym">an-ftree</span> contains a
<span class="RktSym">child</span> with <span class="RktVal">"blue"</span> eyes.</p><p><div class="SIntrapara">Our analysis suggests that the result should be <span class="RktVal">#true</span> if one of the
following three expressions is <span class="RktVal">#true</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#%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="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-eyes</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">"blue"</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="stt"> </span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ul></div><div class="SIntrapara">which, in turn, means we need to combine these expressions 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._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</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~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-eyes</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"blue"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><a href="part_four.html#%28counter._%28figure._fig~3ablue-eyes%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">113</span></a> pulls everything together in a single
definition.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._497))"></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_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</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">does </span><span class="RktSym">an-ftree</span><span class="RktCmt"> contain a </span><span class="RktSym">child</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">structure with </span><span class="RktVal">"blue"</span><span class="RktCmt"> in the </span><span class="RktSym">eyes</span><span class="RktCmt"> field</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</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="RktPn">(</span><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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Gustav</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;</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;&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._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-la
simulate the stepper&rsquo;s action for <span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="stt"> </span><span class="RktSym">Carl</span><span class="RktPn">)</span> to give
you an impression of how it all works:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Let&rsquo;s act as if <span class="RktSym">NP</span> were a value and let&rsquo;s use <span class="RktSym">carl</span> as an
abbreviation for the instance of <span class="RktSym">child</span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">no-parent?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVal">#false</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._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._or%29%29" class="RktStxLink" data-pltdoc="x">or</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~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-eyes</span><span class="hspace">&nbsp;</span><span class="RktSym">carl</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"blue"</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">carl</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">carl</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">After dropping the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line, it&rsquo;s time to replace
<span class="RktSym">carl</span> with its value and to perform the three auxiliary
calculations in <a href="part_four.html#%28counter._%28figure._fig~3acalc-trees%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">114</span></a>. Using these to replace equals
with equals, the rest of the computation is explained easily:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</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~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="hspace">&nbsp;</span><span class="RktVal">"blue"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">carl</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">carl</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span></td></tr></table></blockquote></div><div class="SIntrapara">While we trust that you have seen such auxiliary calculations in your
mathematics courses, you also need to understand that the stepper would
<span style="font-weight: bold">not</span> perform such calculations; instead it works out only those
calculations that are absolutely needed.</div></p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">(1)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">child-eyes</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktVal">"green"</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">(2)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-father</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktVal">#false</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">(3)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">child-mother</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-child</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="hspace">&nbsp;</span><span class="RktVal">"Carl"</span><span class="hspace">&nbsp;</span><span class="RktVal">1926</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">NP</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktVal">#false</span></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acalc-trees))" x-target-lift="Figure"></a>Figure&nbsp;114: </span>Calculating with trees</span></p></blockquote><p><a name="(counter._(exercise._ex~3acount-ft))"></a><span style="font-weight: bold">Exercise</span>&nbsp;310. Develop <span class="RktSym">count-persons</span>. The function
consumes a family tree and counts the <span class="RktSym">child</span> structures in the
tree. <a href="part_four.html#%28counter._%28exercise._ex~3acount-ft%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aage-ft))"></a><span style="font-weight: bold">Exercise</span>&nbsp;311. Develop the function <span class="RktSym">average-age</span>. It
consumes a family tree and the current year. It produces the average
age of all <span class="RktSym">child</span> structures in the family tree. <a href="part_four.html#%28counter._%28exercise._ex~3aage-ft%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aec-ft))"></a><span style="font-weight: bold">Exercise</span>&nbsp;312. Develop the function <span class="RktSym">eye-colors</span>, which
consumes a family tree and produces a list of all eye colors in the
tree. An eye color may occur more than once in the resulting list.
<span style="font-weight: bold">Hint</span> 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._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span> to concatenate the lists resulting from the
recursive calls. <a href="part_four.html#%28counter._%28exercise._ex~3aec-ft%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aproper-bea))"></a><span style="font-weight: bold">Exercise</span>&nbsp;313. Suppose we need the function
<span class="RktSym">blue-eyed-ancestor?</span>, which is like <span class="RktSym">blue-eyed-child?</span> but
responds with <span class="RktVal">#true</span> only when a proper ancestor, not the given
<span class="RktSym">child</span> itself, has blue eyes.</p><p><div class="SIntrapara">Although the goals clearly differ, the signatures are the same:
</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_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.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">blue-eyed-ancestor?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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></table></blockquote></div><div class="SIntrapara">Stop! Formulate a purpose statement for the function.</div></p><p><div class="SIntrapara">To appreciate the difference, we take a look at Eva:
</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">blue-eyed-child?</span><span class="hspace">&nbsp;</span><span class="RktSym">Eva</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Eva is blue-eyed, but has no blue-eyed ancestor. Hence,
</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">blue-eyed-ancestor?</span><span class="hspace">&nbsp;</span><span class="RktSym">Eva</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">In contrast, Gustav is Eva&rsquo;s son and does have a blue-eyed ancestor:
</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">blue-eyed-ancestor?</span><span class="hspace">&nbsp;</span><span class="RktSym">Gustav</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">Now suppose a friend comes up with this solution:<a name="(idx._(gentag._498))"></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">blue-eyed-ancestor?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">no-parent?</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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;&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._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">blue-eyed-ancestor?</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">child-father</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">blue-eyed-ancestor?</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">child-mother</span><span class="hspace">&nbsp;</span><span class="RktSym">an-ftree</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">Explain why this function fails one of its tests. What is the result of
<span class="RktPn">(</span><span class="RktSym">blue-eyed-ancestor?</span><span class="stt"> </span><span class="RktSym">A</span><span class="RktPn">)</span> no matter which <span class="RktSym">A</span> you choose?
Can you fix your friend&rsquo;s solution? <a href="part_four.html#%28counter._%28exercise._ex~3aproper-bea%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><span style="font-weight: bold">Note on variable and structure names</span> The initial discussion of family
relationships suggests the name <span class="RktSym">child</span> for the structure type
definition. The five pieces of information represent the child of particular
parents. The rest of the development is about ancestor trees, however. If you
were to skim the chapter just to focus on function definitions, like the one in
<a href="part_four.html#%28counter._%28figure._fig~3ablue-eyes%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">113</span></a>, the names <span class="RktSym">child-father</span>,
<span class="RktSym">child-mother</span>, and <span class="RktSym">child-eyes</span> might mislead you a bit, mostly
because they might seem to conflict with the recursive nature of the function.
An experienced developer would probably use DrRacket&rsquo;s renaming
functionality<span class="refelem"><span class="refcolumn"><span class="refcontent">Check syntax. Right-click on the name of the
structure. Select rename.</span></span></span> to replace <span class="RktSym">child</span> with <span class="RktSym">person</span>. In
general, variable naming are critical for
helping readers of code to understand the thinking behind it.</p><h4>19.2<tt>&nbsp;</tt><a name="(part._sec~3aforests)"></a>Forests</h4><p><div class="SIntrapara">It is a short step from a family tree to a family forest:
</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">An </span><a name="(tech._ff)"></a><span style="font-style: italic">FF</span><span class="RktCmt"> (short for </span><span style="font-style: italic">family forest</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._ft%29" class="techoutside" data-pltdoc="x"><span class="techinside">FT</span></a><span class="stt"> </span><a href="part_four.html#%28tech._ff%29" class="techoutside" data-pltdoc="x"><span class="techinside">FF</span></a><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"> a family forest represents several</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">families (say, a town) and their ancestor trees</span></td></tr></table></blockquote></div><div class="SIntrapara">Here are some tree excerpts from <a href="part_four.html#%28counter._%28figure._fig~3afamily-tree%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">111</span></a> arranged as forests:
</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">ff1</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">Carl</span><span class="hspace">&nbsp;</span><span class="RktSym">Bettina</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">ff2</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">Fred</span><span class="hspace">&nbsp;</span><span class="RktSym">Eva</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">ff3</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">Fred</span><span class="hspace">&nbsp;</span><span class="RktSym">Eva</span><span class="hspace">&nbsp;</span><span class="RktSym">Carl</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first two forests contain two unrelated families, and the third one
illustrates that unlike in real forests, trees in family forests can
overlap.</div></p><p><div class="SIntrapara">Now consider this representative problem concerning family trees:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design the function <span class="RktSym">blue-eyed-child-in-forest?</span>, which
determines whether a family forest contains a <span class="RktSym">child</span> with
<span class="RktVal">"blue"</span> in the <span class="RktSym">eyes</span> field.</p></blockquote></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._499))"></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_four.html#%28tech._ff%29" class="techoutside" data-pltdoc="x"><span class="techinside">FF</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">does the forest contain any </span><span class="RktSym">child</span><span class="RktCmt"> with </span><span class="RktVal">"blue"</span><span class="RktCmt"> </span><span class="RktSym">eyes</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">blue-eyed-child-in-forest?</span><span class="hspace">&nbsp;</span><span class="RktSym">ff1</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="RktPn">(</span><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">blue-eyed-child-in-forest?</span><span class="hspace">&nbsp;</span><span class="RktSym">ff2</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">blue-eyed-child-in-forest?</span><span class="hspace">&nbsp;</span><span class="RktSym">ff3</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;</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">blue-eyed-child-in-forest?</span><span class="hspace">&nbsp;</span><span class="RktSym">a-forest</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-forest</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;&nbsp;&nbsp;&nbsp;</span><span cl
Study the signature, the purpose statement, and the examples on your own. We
focus on the program organization. Concerning the template, the design may
employ the list template because the function consumes a list. If each item on
the list were a structure with an <span class="RktSym">eyes</span> field and nothing else, the
function would iterate over those structures using the selector function for
the <span class="RktSym">eyes</span> field and a string comparison. In this case, each item is a
family tree, but, luckily, we already know how to process family trees.</p><p>Let&rsquo;s step back and inspect how we explained
<a href="part_four.html#%28counter._%28figure._fig~3ablue-eyed-child%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">115</span></a>. The starting point is a <span style="font-weight: bold">pair</span> of data
definitions where the second refers to the first and both refer to
themselves. The result is a <span style="font-weight: bold">pair</span> of functions where the second refers
to the first and both refer to themselves. In other words, the function
definitions refer to each other the same way the data definitions refer to
each other. Early chapters gloss over this kind of relationship, but now the
situation is sufficiently complicated and deserves attention.</p><p><a name="(counter._(exercise._ex~3afamily-forest1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;314. Reformulate the data definition for <a href="part_four.html#%28tech._ff%29" class="techoutside" data-pltdoc="x"><span class="techinside">FF</span></a>
with the <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> abstraction. Now do the same for
the <span class="RktSym">blue-eyed-child-in-forest?</span> function. Finally, define
<span class="RktSym">blue-eyed-child-in-forest?</span> using one of the list abstractions from
the preceding chapter. <a href="part_four.html#%28counter._%28exercise._ex~3afamily-forest1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afamily-forest2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;315. Design the function <span class="RktSym">average-age</span>. It
consumes a family forest and a year (<a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a>). From this data, it
produces the average age of all <span class="RktSym">child</span> instances in the
forest. <span style="font-weight: bold">Note</span> If the trees in this forest overlap, the result isn&rsquo;t
a true average because some people contribute more than others. For this
exercise, act as if the trees don&rsquo;t overlap. <a href="part_four.html#%28counter._%28exercise._ex~3afamily-forest2%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>19.3<tt>&nbsp;</tt><a name="(part._sec~3asexp)"></a>S-expressions</h4><p><div class="SIntrapara">While <a href="i2-3.html" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a> introduced S-expressions on an informal basis, it is
possible to describe them with a combination of three data
definitions:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._s._expr)"></a><span style="font-style: italic">S-expr</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><a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a></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">An </span><a name="(tech._sl)"></a><span style="font-style: italic">SL</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="stt"> </span><a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._atom)"></a><span style="font-style: italic">Atom</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><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><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"> </span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">Recall that <a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a>s look like strings with a
single quote at the beginning and with no quote at the end.</div></p><p>The idea of S-expressions is due to John McCarthy and his Lispers, who
created S-expressions in 1958 so that they could process Lisp programs with
other Lisp programs. This seemingly circular reasoning may sound esoteric,
but, as mentioned in <a href="i2-3.html" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a>, S-expressions are a versatile form of
data that is often rediscovered, most recently with applications to the
world wide web. Working with S-expressions thus prepares a discussion of
how to design functions for highly intertwined data definitions.</p><p><a name="(counter._(exercise._ex~3aatom))"></a><span style="font-weight: bold">Exercise</span>&nbsp;316. Define the <span class="RktSym">atom?</span> function. <a href="part_four.html#%28counter._%28exercise._ex~3aatom%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Up to this point in this book, no data has required a data definition as
complex as the one for S-expressions. And yet, with one extra hint, you
can design functions that process S-expressions if you follow the design
recipe. To demonstrate this point, let&rsquo;s work through a specific example:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design the function <span class="RktSym">count</span>, which determines
how many times some symbol occurs in some S-expression.</p></blockquote></div><div class="SIntrapara">While the first step calls for data definitions and appears to have been
completed, remember that it also calls for the creation of data examples,
especially when the definition is complex.</div></p><p><div class="SIntrapara">A data definition is supposed to be a prescription of how to create data,
and its &ldquo;test&rdquo; is whether it is usable. One point that the data
definition for <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> makes is that every <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> is an element
of <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>, and you know that <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>s are easy to fabricate:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktVal">'</span><span class="RktVal">hello</span></td></tr><tr><td><span class="RktVal">20.12</span></td></tr><tr><td><span class="RktVal">"world"</span></td></tr></table></blockquote></div><div class="SIntrapara">In the same vein, every <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> is a list as well as an <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</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">20.12</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">"world"</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="RktPn">(</span><span class="RktSym"><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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</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">20.12</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">"world"</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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first two are obvious; the third one deserves a second look. It repeats
the second <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> but nested inside <span class="RktPn">(</span><span class="RktSym"><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"><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">(</span><span class="RktVal">)</span><span class="RktPn">)</span>. What
this means is that it is a list that contains a single item, namely,
the second example. You can simplify the example 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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</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">20.12</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">"world"</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><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">or </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&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">hello</span><span class="hspace">&nbsp;</span><span class="RktVal">20.12</span><span class="hspace">&nbsp;</span><span class="RktVal">"world"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Indeed, with the quotation mechanism of <a href="i2-3.html" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a> it is even easier to
write down S-expressions. Here are the last three:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">'()</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">hello</span><span class="hspace">&nbsp;</span><span class="RktVal">20.12</span><span class="hspace">&nbsp;</span><span class="RktVal">"world"</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list 'hello #i20.12 "world")</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">hello</span><span class="hspace">&nbsp;</span><span class="RktVal">20.12</span><span class="hspace">&nbsp;</span><span class="RktVal">"world"</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list (list 'hello #i20.12 "world"))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">To help you out, we evaluate these examples in the interactions area of
DrRacket so that you can see the result, which is closer to the above
constructions than 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._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</a></span> notation.</div></p><p><div class="SIntrapara">With <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</a></span>, it is quite easy to make up complex examples:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">define</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">f</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">+</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">55</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list 'define (list 'f 'x) (list '+ 'x 55))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">This example may strike you as odd because it looks like a definition in
BSL, but, as the interaction with DrRacket shows, it is just a piece of
data. Here is another one:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">6</span><span class="hspace">&nbsp;</span><span class="RktVal">f</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktVal">e</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">d</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">(list (list 6 'f) (list 5 'e) (list 4 'd))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">This piece of data looks like a table, associating letters with
numbers. The last example is a piece of art:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">wing</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">wing</span><span class="hspace">&nbsp;</span><span class="RktVal">body</span><span class="hspace">&nbsp;</span><span class="RktVal">wing</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">wing</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list 'wing (list 'wing 'body 'wing) 'wing)</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">It is now time to write down the rather obvious header for <span class="RktSym">count</span>:<a name="(idx._(gentag._500))"></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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</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_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">counts all occurrences of </span><span class="RktSym">sy</span><span class="RktCmt"> in </span><span class="RktSym">sexp</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Since the header is obvious, we move on to functional examples.
If the given <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> is <span class="RktVal">'</span><span class="RktVal">world</span> and the to-be-counted symbol
is <span class="RktVal">'</span><span class="RktVal">world</span>, the answer is obviously <span class="RktVal">1</span>. Here are some more
examples, immediately formulated as tests:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">world</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</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="RktPn">(</span><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">count</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">world</span><span class="hspace">&nbsp;</span><span class="RktVal">hello</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</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="RktPn">(</span><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">count</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">world</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">hello</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">hello</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">hello</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You can see how convenient quotation notation is for test cases. When it
comes to templates, however, thinking in terms 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> is disastrous.</div></p><p><div class="SIntrapara">Before we move on to the template step, we need to prepare you for the next
generalization of the design recipe:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Hint</span>
For intertwined data definitions, create one template per data
definition. Create them in parallel. Make sure they refer to each other
in the same way the data definitions do. <span style="font-weight: bold">End</span></p></blockquote></div><div class="SIntrapara">This hint sounds more complicated than it is. For our problem, it means we
need three templates:
</div><div class="SIntrapara"><ol><li><p>one for <span class="RktSym">count</span>, which counts occurrences of symbols in <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>s;</p></li><li><p>one for a function that counts occurrences of symbols in <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a>s; and</p></li><li><p>one for a function that counts occurrences of symbols in <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>s.</p></li></ol></div></p><p><div class="SIntrapara">And here are three partial templates, with conditionals as suggested by the three data definitions:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><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">count</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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#%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;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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;</span><span class="RktPn">[</span><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="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><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">count-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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">sl</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>
because the data definition for <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> has two clauses. It uses the
<span class="RktSym">atom?</span> function to distinguish the case for <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>s from the
case for <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a>s. The template named <span class="RktSym">count-sl</span> consumes an
element of <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> and a symbol, and because <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> is basically a
list, <span class="RktSym">count-sl</span> also contains a two-pronged <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>. Finally,
<span class="RktSym">count-atom</span> is supposed to work for both <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>s and
<a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a>s. And this means that its template checks for the three
distinct forms of data mentioned in the data definition of <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>.</div></p><p><div class="SIntrapara">The next step is to take apart compound data in the relevant clauses:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><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">count</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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#%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;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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;</span><span class="RktPn">[</span><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="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><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">count-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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">sl</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>
self-references in the data definitions. In our context, this means
self-references <span style="font-weight: bold">and</span> references from one data definition to another
and (possibly) back. Let&rsquo;s inspect 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> lines in the three
templates:
</div><div class="SIntrapara"><ol><li><p>The <span class="RktSym">atom?</span> line in <span class="RktSym">count</span> corresponds to the first
line in the definition of <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>. To indicate the cross-reference
from here to <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>, we add <span class="RktPn">(</span><span class="RktSym">count-atom</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="stt"> </span><span class="RktSym">sy</span><span class="RktPn">)</span>, meaning we
interpret <span class="RktSym">sexp</span> as an <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> and let the appropriate function
deal with it.</p></li><li><p>Following the same line of thought, the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line in
<span class="RktSym">count</span> calls for the addition of <span class="RktPn">(</span><span class="RktSym">count-sl</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="stt"> </span><span class="RktSym">sy</span><span class="RktPn">)</span>.</p></li><li><p>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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span> line in <span class="RktSym">count-sl</span> corresponds to a line in
the data definition that makes no reference to another data definition.</p></li><li><p>In contrast, the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span> line contains two selector expressions,
and each extracts a different kind of value. Specifically,
<span class="RktPn">(</span><span class="RktSym"><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">sl</span><span class="RktPn">)</span> is an element of <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>, which means that we
wrap it in <span class="RktPn">(</span><span class="RktSym">count</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span>. After all, <span class="RktSym">count</span> is
responsible for counting inside of arbitrary <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>s. Next,
<span class="RktPn">(</span><span class="RktSym"><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">sl</span><span class="RktPn">)</span> corresponds to a self-reference, and we know that
we need to deal with those via recursive function calls.</p></li><li><p>Finally, all three cases in <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> refer to atomic forms of
data. Therefore the <span class="RktSym">count-atom</span> function does not need to change.</p></li></ol></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._502))"></a>
<a name="(idx._(gentag._503))"></a>
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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#%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;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="RktPn">]</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#%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;</span><span class="RktPn">(</span><span class="RktSym">count-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.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">count-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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">sl</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/intermed
<a name="(idx._(gentag._505))"></a>
<a name="(idx._(gentag._506))"></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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</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_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">counts all occurrences of </span><span class="RktSym">sy</span><span class="RktCmt"> in </span><span class="RktSym">sexp</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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#%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;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="RktPn">]</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#%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">count-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</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_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</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_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">counts all occurrences of </span><span class="RktSym">sy</span><span class="RktCmt"> in </span><span class="RktSym">sl</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><
Filling in the blanks in these templates is straightforward, as
<a href="part_four.html#%28counter._%28figure._fig~3asexp-function%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">117</span></a> shows. You ought to be able to explain any
random line in the three definitions. For example:</p><blockquote class="SCodeFlow"><p><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="RktPn">]</span></p></blockquote><p> determines whether <span class="RktSym">sexp</span> is an <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> and, if so,
interprets the <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> as an <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> via
<span class="RktSym">count-atom</span>.</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._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></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._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count</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">sl</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">count-sl</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">sl</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr></table></blockquote><p>means the given list consists of two parts: an <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>
and an <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a>. By using <span class="RktSym">count</span> and <span class="RktSym">count-sl</span>, the
corresponding functions are used to count how often <span class="RktSym">sy</span> appears in
each part, and the two numbers are added up&#8212;<wbr></wbr>yielding the total number of
<span class="RktSym">sy</span>s in all of <span class="RktSym">sexp</span>.</p><blockquote class="SCodeFlow"><p><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._symbol~3f%29%29" class="RktValLink" data-pltdoc="x">symbol?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">at</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._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="RktSym">at</span><span class="hspace">&nbsp;</span><span class="RktSym">sy</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">]</span></p></blockquote><p> tells us that if an <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> is a <a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a>, <span class="RktSym">sy</span>
occurs once if it is equal to <span class="RktSym">sexp</span> and otherwise it does not
occur at all. Since the two pieces of data are atomic, there is no other
possibility.</p><p><a name="(counter._(exercise._ex~3acount-local))"></a><span style="font-weight: bold">Exercise</span>&nbsp;317. A program that consists of three connected
functions ought to express this relationship with a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
expression.</p><p>Copy and reorganize the program from <a href="part_four.html#%28counter._%28figure._fig~3asexp-function%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">117</span></a> into a
single function using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>. Validate the revised code with the
<a name="(idx._(gentag._507))"></a>test suite for <span class="RktSym">count</span>.</p><p>The second argument to the local functions, <span class="RktSym">sy</span>, never changes. It
is always the same as the original symbol. Hence you can eliminate it from
the local function definitions to tell the reader that <span class="RktSym">sy</span> is a
constant across the traversal process. <a href="part_four.html#%28counter._%28exercise._ex~3acount-local%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adepth))"></a><span style="font-weight: bold">Exercise</span>&nbsp;318. Design <span class="RktSym">depth</span>. The function consumes an
S-expression and determines its depth. An <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> has a depth of
<span class="RktVal">1</span>. The depth of a list of S-expressions is the maximum depth of
its items plus <span class="RktVal">1</span>. <a href="part_four.html#%28counter._%28exercise._ex~3adepth%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3asubstitute))"></a><span style="font-weight: bold">Exercise</span>&nbsp;319. Design <span class="RktSym">substitute</span>. It
consumes an S-expression <span class="RktSym">s</span> and two symbols, <span class="RktSym">old</span> and
<span class="RktSym">new</span>. The result is like <span class="RktSym">s</span> with all occurrences of
<span class="RktSym">old</span> replaced by <span class="RktSym">new</span>. <a href="part_four.html#%28counter._%28exercise._ex~3asubstitute%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3asexpr-abstract1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;320. Practice the step from data definition to
function design with two changes to the definition of <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>.</p><p>For the first step, reformulate the data definition for <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> so
that the first clause of the first data definition is expanded into the
three clauses of <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> and the second data definition uses the
<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> abstraction. Redesign the <span class="RktSym">count</span> function for this data
definition.</p><p>For the second step, Integrate the data definition of <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> into the
one for <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>. Simplify <span class="RktSym">count</span> again. <span style="font-weight: bold">Hint</span> Use
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>. <a href="part_four.html#%28counter._%28exercise._ex~3asexpr-abstract1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3asexpr-abstract2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;321. Abstract the data definitions for
<a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> and <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> so that they abstract over the kinds of <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a>s
that may appear. <a href="part_four.html#%28counter._%28exercise._ex~3asexpr-abstract2%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>19.4<tt>&nbsp;</tt><a name="(part._sec~3adesign-.N)"></a>Designing with Intertwined Data</h4><p><div class="SIntrapara">The jump from <a name="(idx._(gentag._508))"></a>self-referential data definitions to collections of
<a name="(idx._(gentag._509))"></a>data definitions with mutual references is far smaller than
the one from data definitions for finite data to self-referential data
definitions. Indeed, the design recipe for self-referential data
definitions&#8212;<wbr></wbr>see <a href="part_two.html#%28part._ch~3adesign-lists%29" data-pltdoc="x">Designing with Self-Referential Data Definitions</a>&#8212;<wbr></wbr>needs only minor adjustments
to apply to this seemingly complex situation:
</div><div class="SIntrapara"><ol><li><p>The need for &ldquo;nests&rdquo; of mutually related data definitions is similar
to the one to the need for self-referential data definitions. The problem
statement deals with many distinct kinds of information, and one form of
information refers to other kinds.</p><p>Before you proceed in such situations, draw arrows to connect references to
definitions. Consider the left side of
<a href="part_four.html#%28counter._%28figure._fig~3adef-data-mutual-arrows%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">118</span></a>. It displays the definition for
<a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>, which contains references to <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> and <a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a> that
are connected to their respective definitions via arrows. Similarly,
the definition of <a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a> contains one self-reference and one reference
back to <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a>; again, both are connected by appropriate arrows.</p><p>Like self-referential data definitions, these nests of definitions also
call for validation. At a minimum, you must be able to construct some
examples for every individual definition. Start from clauses that do not
refer to any of the other data definitions in the nest. Keep in mind that
the definition may be invalid if it is impossible to generate examples
from them.</p></li><li><p>The key change is that you must design as many functions in parallel
as there are data definitions. Each function specializes for one of the
data definitions; all remaining arguments remain the same. Based on that,
you start with a signature, a purpose statement, and a dummy definition
<span style="font-weight: bold">for each function</span>.</p></li><li><p>Be sure to work through functional examples that use all mutual
references in the nest of data definitions.</p></li><li><p>For each function, design the template according to its primary data
definition. Use <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">52</span></a> to guide the template creation
up to the last step. The revised last step calls for a check for all
self-references and cross-references. Use the data definitions annotated
with arrows to guide this step. For each arrow in the data definitions,
include an arrow in the templates. See the right side of
<a href="part_four.html#%28counter._%28figure._fig~3adef-data-mutual-arrows%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">118</span></a> for the arrow-annotated version of
the templates.</p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_141.png" alt="image" width="156.888671875" height="304.328125"/></p></td><td valign="top"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td valign="top"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_142.png" alt="image" width="235.99609375" height="304.328125"/></p></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adef-data-mutual-arrows))" x-target-lift="Figure"></a>Figure&nbsp;118: </span>Arrows for nests of data definitions and templates</span></p></blockquote><p>Now replace the arrows with actual function calls. As you gain
experience, you will naturally skip the arrow-drawing step and use
function calls directly.</p><p><span style="font-weight: bold">Note</span> Observe how both nests&#8212;<wbr></wbr>the one for data definitions and the one
for function templates&#8212;<wbr></wbr>contain four arrows, and note how pairs of arrows
correspond to each other. Researchers call this correspondence a
<span style="font-style: italic">symmetry</span>. It is evidence that the design recipe provides a
natural way for going from problems to solutions.</p></li><li><p>For the design of the body, we start with those <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> lines
that do not contain natural recursions or calls to other functions. They
are called <span style="font-style: italic">base cases</span>. The corresponding answers are typically
easy to formulate or are already given by the examples. After that, you
deal with the self-referential cases and the cases of cross-function
calls. Let the questions and answers of <a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">53</span></a> guide
you.</p></li><li><p>Run the tests when all definitions are completed. If an auxiliary
function is broken, you may get two error reports, one for the main
function and another one for the flawed auxiliary definition. A
<span style="font-weight: bold">single</span> fix should eliminate both. Do make sure that running the
tests covers all the pieces of the function.</p></li></ol></div><div class="SIntrapara">Finally, if you are stuck in step 5, remember the table-based approach to
guessing the combination function. In the case of intertwined data, you may
need not only a table per case but also a table per case and per function to
work out the combination.</div></p><h4>19.5<tt>&nbsp;</tt><a name="(part._sec~3aproj-bst)"></a>Project: BSTs</h4><p>Programmers often work with tree representations of data to improve the
performance of their functions. A particularly well-known form of tree is the
<span style="font-weight: bold">binary search tree</span> because it is a good way to store and retrieve
information quickly.</p><p><div class="SIntrapara">To be concrete, let&rsquo;s discuss binary trees that manage information about
people. Instead of the <span class="RktSym">child</span><span class="RktMeta"></span> structures in family trees, a binary
tree contains <span class="RktSym">node</span><span class="RktMeta"></span>s:
</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">no-info</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-no-info</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">node</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">ssn</span><span class="hspace">&nbsp;</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></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._bt)"></a><span style="font-style: italic">BT</span><span class="RktCmt"> (short for </span><a name="(tech._binarytree)"></a><span style="font-style: italic">BinaryTree</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="RktSym">NONE</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_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><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="stt"> </span><a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a><span class="stt"> </span><a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The corresponding data definition is like the one for family trees with
<span class="RktSym">NONE</span><span class="RktMeta"></span> indicating a lack of information and each <span class="RktSym">node</span>
recording a social security number, a name, and two other binary
trees. The latter are like the parents of family trees,
though the relationship between a <span class="RktSym">node</span><span class="RktMeta"></span> and its <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="RktMeta"></span> and
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span><span class="RktMeta"></span> trees is not based on family relationships.</div></p><p><div class="SIntrapara">Here are two binary trees:
</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">make-node</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">15</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">d</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">NONE</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">24</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">i</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><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="RktVal">15</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">d</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-node</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">87</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">h</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">NONE</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div></p><p><a href="part_four.html#%28counter._%28figure._fig~3abst%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">119</span></a> shows how we should think about such trees as
drawings. The trees are drawn upside down, with the root at the top and the
crown of the tree at the bottom. Each circle corresponds to a node, labeled
with the <span class="RktSym">ssn</span><span class="RktMeta"></span> field of a corresponding <span class="RktSym">node</span><span class="RktMeta"></span> structure. The
drawings omit <span class="RktSym">NONE</span><span class="RktMeta"></span>.</p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0"><tr><td><p>tree A</p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p>tree B</p></td></tr><tr><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p></p></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_143.png" alt="image" width="289.0" height="209.0"/></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_144.png" alt="image" width="289.0" height="209.0"/></p></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3abst))" x-target-lift="Figure"></a>Figure&nbsp;119: </span>A binary search tree and a binary tree</span></p></blockquote><p><a name="(counter._(exercise._ex~3abst1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;322. Draw the above two trees in the manner of
<a href="part_four.html#%28counter._%28figure._fig~3abst%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">119</span></a>. Then design <span class="RktSym">contains-bt?</span><span class="RktMeta"></span>, which determines
whether a given number occurs in some given <span class="RktSym">BT</span>. <a href="part_four.html#%28counter._%28exercise._ex~3abst1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3abst1-search))"></a><span style="font-weight: bold">Exercise</span>&nbsp;323. Design <span class="RktSym">search-bt</span><span class="RktMeta"></span>. The function consumes
a number <span class="RktSym">n</span><span class="RktMeta"></span> and a <span class="RktSym">BT</span><span class="RktMeta"></span>. If the tree contains a <span class="RktSym">node</span><span class="RktMeta"></span>
structure whose <span class="RktSym">ssn</span><span class="RktMeta"></span> field is <span class="RktSym">n</span><span class="RktMeta"></span>, the function produces the
value of the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._name%29%29" class="RktStxLink" data-pltdoc="x">name</a></span><span class="RktMeta"></span> field in that node. Otherwise, the function
produces <span class="RktVal">#false</span><span class="RktMeta"></span>.</p><p><span style="font-weight: bold">Hint</span> Consider using <span class="RktSym">contains-bt?</span><span class="RktMeta"></span> to check the entire tree
first or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span> to check the result of the natural recursion at
each stage. <a href="part_four.html#%28counter._%28exercise._ex~3abst1-search%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">If we read the numbers in the two trees in <a href="part_four.html#%28counter._%28figure._fig~3abst%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">119</span></a> from left
to right, we obtain two different sequences:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left"><p>tree A</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>10</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>15</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>24</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>29</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>63</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>77</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>89</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>95</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>99</p></td></tr><tr><td align="left"><p>tree B</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>87</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>15</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>24</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>29</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>63</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>33</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>89</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>95</p></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><p>99</p></td></tr></table></blockquote></div><div class="SIntrapara">The sequence for tree A is sorted in ascending order the one for B is
not. A binary tree of the first kind is a <span style="font-weight: bold">binary search
tree</span>. Every binary search tree is a binary tree, but not every binary
tree is a binary search tree. More concretely, we formulate a
condition&#8212;<wbr></wbr>or data invariant&#8212;<wbr></wbr>that distinguishes a binary search tree
from a binary tree:</div></p><p><span style="font-weight: bold">The BST Invariant</span></p><p><div class="SIntrapara"><blockquote><p><div class="SIntrapara">A <a name="(tech._bst)"></a><span style="font-style: italic">BST</span> (short for <a name="(tech._binary._search._tree)"></a><span style="font-style: italic">binary search tree</span>) is a <a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a>
according to the following conditions:
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">NONE</span> is always a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>.</p></li><li><p><div class="SIntrapara"><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="stt"> </span><span class="RktSym">ssn0</span><span class="stt"> </span><span class="RktSym">name0</span><span class="stt"> </span><span class="RktSym">L</span><span class="stt"> </span><span class="RktSym">R</span><span class="RktPn">)</span> is a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> if
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">L</span> is a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>,</p></li><li><p><span class="RktSym">R</span> is a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>,</p></li><li><p>all <span class="RktSym">ssn</span> fields in <span class="RktSym">L</span> are smaller than <span class="RktSym">ssn0</span>,</p></li><li><p>all <span class="RktSym">ssn</span> fields in <span class="RktSym">R</span> are larger than <span class="RktSym">ssn0</span>.</p></li></ul></div></p></li></ul></div></p></blockquote></div><div class="SIntrapara">In other words, to check whether a <a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a> also belongs to <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>,
we must inspect all numbers in all subtrees and ensure that they are
smaller or larger than some given number. This places an additional burden
on the construction of data, but, as the following exercises show,
it is well worth it.</div></p><p><a name="(counter._(exercise._ex~3abst0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;324. Design the function <span class="RktSym">inorder</span><span class="RktMeta"></span>. It consumes a
binary tree and produces the sequence of all the <span class="RktSym">ssn</span><span class="RktMeta"></span> numbers in the
tree as they show up from left to right when looking at a tree drawing.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hint</span> 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._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="RktMeta"></span>, which concatenates lists like thus:
</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._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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</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="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="RktVal">4</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="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktVal">6</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></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</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="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktVal">6</span><span class="hspace">&nbsp;</span><span class="RktVal">7</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">What does <span class="RktSym">inorder</span><span class="RktMeta"></span> produce for a binary search tree? <a href="part_four.html#%28counter._%28exercise._ex~3abst0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p>Looking for a <span class="RktSym">node</span><span class="RktMeta"></span> with a given <span class="RktSym">ssn</span> in a <span class="RktSym">BST</span><span class="RktMeta"></span> may
exploit the <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> invariant. To find out whether a <span class="RktSym">BT</span><span class="RktMeta"></span> contains
a node with a specific <span class="RktSym">ssn</span><span class="RktMeta"></span>, a function may have to look at
every <span class="RktSym">node</span><span class="RktMeta"></span> of the tree. In contrast, to find out whether a binary
<span style="font-weight: bold">search</span> tree contains the same <span class="RktSym">ssn</span>, a function may eliminate
one of two subtrees for every node it inspects.</p><p><div class="SIntrapara">Let&rsquo;s illustrate the idea with this sample <span class="RktSym">BST</span><span class="RktMeta"></span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktVal">66</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nbsp;</span><span class="RktSym">L</span><span class="hspace">&nbsp;</span><span class="RktSym">R</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">If we are looking for <span class="RktVal">66</span><span class="RktMeta"></span>, we have found the node we are looking
for. Now, if we are looking for a smaller number, say <span class="RktVal">63</span><span class="RktMeta"></span>, we can
focus the search on <span class="RktSym">L</span><span class="RktMeta"></span> because <span style="font-weight: bold">all</span> <span class="RktSym">node</span><span class="RktMeta"></span>s with
<span class="RktSym">ssn</span><span class="RktMeta"></span> fields smaller than <span class="RktVal">66</span><span class="RktMeta"></span> are in <span class="RktSym">L</span><span class="RktMeta"></span>. Similarly, if we
were to look for <span class="RktVal">99</span><span class="RktMeta"></span>, we would ignore <span class="RktSym">L</span><span class="RktMeta"></span> and focus on <span class="RktSym">R</span><span class="RktMeta"></span>
because <span style="font-weight: bold">all</span> <span class="RktSym">node</span><span class="RktMeta"></span>s with <span class="RktSym">ssn</span><span class="RktMeta"></span>s larger than <span class="RktVal">66</span><span class="RktMeta"></span> are
in <span class="RktSym">R</span><span class="RktMeta"></span>.</div></p><p><a name="(counter._(exercise._ex~3abst2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;325. Design <span class="RktSym">search-bst</span><span class="RktMeta"></span>. The function consumes a
number <span class="RktSym">n</span><span class="RktMeta"></span> and a <span class="RktSym">BST</span><span class="RktMeta"></span>. If the tree contains a <span class="RktSym">node</span><span class="RktMeta"></span> whose
<span class="RktSym">ssn</span><span class="RktMeta"></span> field is <span class="RktSym">n</span><span class="RktMeta"></span>, the function produces the value of the
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._name%29%29" class="RktStxLink" data-pltdoc="x">name</a></span><span class="RktMeta"></span> field in that node. Otherwise, the function produces
<span class="RktSym">NONE</span><span class="RktMeta"></span>. The function organization must exploit the BST invariant so
that the function performs as few comparisons as necessary.</p><p>See <a href="part_two.html#%28counter._%28exercise._ex~3asort2%29%29" data-pltdoc="x">exercise&nbsp;189</a> for searching in sorted lists. Compare! <a href="part_four.html#%28counter._%28exercise._ex~3abst2%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Building a binary tree is easy; building a binary search tree is
complicated. Given any two <a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a>s, a number, and a name, we simply
apply <span class="RktSym">make-node</span> to these values in the correct order, and voil&#224;,
we get a new <a href="part_four.html#%28tech._bt%29" class="techoutside" data-pltdoc="x"><span class="techinside">BT</span></a>. This same procedure fails for <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>s because
the result would typically not be a <span class="RktSym">BST</span><span class="RktMeta"></span>. For example, if one
<a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> contains nodes with <span class="RktSym">ssn</span> fields <span class="RktVal">3</span><span class="RktMeta"></span> and <span class="RktVal">5</span><span class="RktMeta"></span>
in the correct order, and the other one contains <span class="RktSym">ssn</span> fields
<span class="RktVal">2</span><span class="RktMeta"></span> and <span class="RktVal">6</span><span class="RktMeta"></span>, simply combining the two trees with another social
security number and a name does not produce a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>.</p><p>The remaining two exercises explain how to build a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> from a list
of numbers and names. Specifically, the first exercise calls for a
function that inserts a given <span class="RktSym">ssn0</span> and <span class="RktSym">name0</span> into a
<a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a>; that is, it produces a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> like the one it is given
with one more node inserted containing <span class="RktSym">ssn0</span>, <span class="RktSym">name0</span>, and
<span class="RktSym">NONE</span> subtrees. The second exercise then requests a function that
can deal with a complete list of numbers and names.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3abst3))"></a><span style="font-weight: bold">Exercise</span>&nbsp;326. Design the function <span class="RktSym">create-bst</span><span class="RktMeta"></span>. It consumes a
<span class="RktSym">BST</span><span class="RktMeta"></span> <span class="RktSym">B</span><span class="RktMeta"></span>, a number <span class="RktSym">N</span><span class="RktMeta"></span>, and a symbol <span class="RktSym">S</span><span class="RktMeta"></span>. It produces
a <span class="RktSym">BST</span><span class="RktMeta"></span> that is just like <span class="RktSym">B</span><span class="RktMeta"></span> and that in place of one
<span class="RktSym">NONE</span><span class="RktMeta"></span> subtree contains the <span class="RktSym">node</span><span class="RktMeta"></span> structure
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-node</span><span class="hspace">&nbsp;</span><span class="RktSym">N</span><span class="hspace">&nbsp;</span><span class="RktSym">S</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="hspace">&nbsp;</span><span class="RktSym">NONE</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Once the design is completed, use the function on tree A from <a href="part_four.html#%28counter._%28figure._fig~3abst%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">119</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3abst3%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3abst4))"></a><span style="font-weight: bold">Exercise</span>&nbsp;327. Design the function <span class="RktSym">create-bst-from-list</span><span class="RktMeta"></span>. It
consumes a list of numbers and names and produces a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> by
repeatedly applying <span class="RktSym">create-bst</span>. Here is the signature:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><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_three.html#%28tech._sim-dd._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">List</span></a><span class="RktCmt"> Number Symbol]] -&gt; </span><a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a></p></blockquote></div><div class="SIntrapara">Use the complete function to create a <a href="part_four.html#%28tech._bst%29" class="techoutside" data-pltdoc="x"><span class="techinside">BST</span></a> from this sample input:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">99</span><span class="hspace">&nbsp;</span><span class="RktVal">o</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">77</span><span class="hspace">&nbsp;</span><span class="RktVal">l</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">24</span><span class="hspace">&nbsp;</span><span class="RktVal">i</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktVal">h</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">95</span><span class="hspace">&nbsp;</span><span class="RktVal">g</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">15</span><span class="hspace">&nbsp;</span><span class="RktVal">d</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">89</span><span class="hspace">&nbsp;</span><span class="RktVal">c</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">29</span><span class="hspace">&nbsp;</span><span class="RktVal">b</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">63</span><span class="hspace">&nbsp;</span><span class="RktVal">a</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The result is tree A in <a href="part_four.html#%28counter._%28figure._fig~3abst%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">119</span></a>, if you follow the <a name="(idx._(gentag._510))"></a>structural
design recipe. If you use an existing abstraction, you may still get this
tree but you may also get an &ldquo;inverted&rdquo; one. Why? <a href="part_four.html#%28counter._%28exercise._ex~3abst4%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>19.6<tt>&nbsp;</tt><a name="(part._sec~3asimplification)"></a>Simplifying Functions</h4><p><a href="part_four.html#%28counter._%28exercise._ex~3acount-local%29%29" data-pltdoc="x">Exercise&nbsp;317</a> shows how to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> to organize a
function that deals with an intertwined form of data. This organization
also helps simplify functions once we know that the data definition is
final. To demonstrate this point, we explain how to simplify the solution
of <a href="part_four.html#%28counter._%28exercise._ex~3asubstitute%29%29" data-pltdoc="x">exercise&nbsp;319</a>.</p><p><div class="SIntrapara"><a name="(idx._(gentag._511))"></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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</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"> </span><a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">replaces all occurrences of </span><span class="RktSym">old</span><span class="RktCmt"> in </span><span class="RktSym">sexp</span><span class="RktCmt"> with </span><span class="RktSym">new</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">substitute</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">world</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">bye</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">bye</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">bye</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">42</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">(</span><span class="RktVal">world</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">42</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">42</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">substitute</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="hspace">&nbsp;</span><span class="RktSym">new</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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nb
<span class="RktSym">substitute</span> function. The definition 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> and three
auxiliary functions as suggested by the data definition. The figure
includes a test case so that you can retest the function after each edit
suggested below. Stop! Develop additional test cases; one is almost never
enough.</p><p><a name="(counter._(exercise._ex~3asimplify1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;328. Copy and paste <a href="part_four.html#%28counter._%28figure._fig~3asimplifying1%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">120</span></a> into
DrRacket; include your test suite. Validate the test suite. As you read along
the remainder of this section, perform the edits and rerun the test suites
to confirm the validity of our arguments. <a href="part_four.html#%28counter._%28exercise._ex~3asimplify1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._512))"></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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">substitute</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="hspace">&nbsp;</span><span class="RktSym">new</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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</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">for-sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">for-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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">for-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> to simplify <span class="RktSym">for-sl</span>. See
<a href="part_four.html#%28counter._%28figure._fig~3asimplifying2%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">121</span></a> for the result. While the original program
says that <span class="RktSym">for-sexp</span> is applied to every item on <span class="RktSym">sl</span>, its
revised definition expresses the same idea more succinctly 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._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>.</p><p>For the second simplification step, we need to remind you 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._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span> compares two arbitrary values. With this in mind, the
third <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> function becomes a
one-liner. <a href="part_four.html#%28counter._%28figure._fig~3asimplifying3%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">122</span></a> displays this second
simplification.</p><p><div class="SIntrapara"><a name="(idx._(gentag._513))"></a>
<a name="(idx._(gentag._514))"></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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">substitute</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="hspace">&nbsp;</span><span class="RktSym">new</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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</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">for-sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">for-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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">for-sl</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp
line. Furthermore, neither definition is recursive. Hence we can
<span style="font-style: italic">in-line</span> the functions in <span class="RktSym">for-sexp</span>. In-lining means
replacing <span class="RktPn">(</span><span class="RktSym">for-atom</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="RktPn">)</span> with <span class="RktPn">(</span><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="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._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="stt"> </span><span class="RktSym">sexp</span><span class="stt"> </span><span class="RktSym">old</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">new</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="RktPn">)</span>, that is, we replace the<span class="refelem"><span class="refcolumn"><span class="refcontent">While <span class="RktSym">sexp</span> is also a
parameter, this substitution is really acceptable because it, too, stands
in for an actual value.</span></span></span> parameter <span class="RktSym">at</span> with the actual argument
<span class="RktSym">sexp</span>. Similarly, for <span class="RktPn">(</span><span class="RktSym">for-sl</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="RktPn">)</span> we put 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._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="stt"> </span><span class="RktSym">for-sexp</span><span class="stt"> </span><span class="RktSym">sexp</span><span class="RktPn">)</span>; see the bottom half of
<a href="part_four.html#%28counter._%28figure._fig~3asimplifying2%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">121</span></a>. All we are left with now is a function
whose definition introduces one <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> function, which is called
on the same major argument. If we systematically supplied the other two
arguments, we would immediately see that the locally defined function can
be used in lieu of the outer one.</p><p><div class="SIntrapara">Here is the result of translating this last thought into code: <a name="(idx._(gentag._515))"></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">substitute</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="hspace">&nbsp;</span><span class="RktSym">new</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">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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._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._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">new</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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._map%29%29" class="RktValLink" data-pltdoc="x">map</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">s</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">substitute</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="hspace">&nbsp;</span><span class="RktSym">old</span><span class="hspace">&nbsp;</span><span class="RktSym">new</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">sexp</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! Explain why we had to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> for this last
simplification.</div></p><h3>20<tt>&nbsp;</tt><a name="(part._ch~3afiles)"></a>Iterative Refinement</h3><p>When you develop real-world programs, you may confront complex forms of
information and the problem of representing them with data. The best strategy to
approach this task is to use <a name="(idx._(gentag._516))"></a><span style="font-style: italic">iterative refinement</span>, a well-known scientific
process. A scientist&rsquo;s problem is to represent a part of the real world, using
some form of mathematics. The result of the effort is called a model. The
scientist then tests the model in many ways, in particular by predicting the
outcome of experiments. If the discrepancies between the predictions and the
measurements are too large, the model is refined with the goal of improving the
predictions. This iterative process continues until the predictions are
sufficiently accurate.</p><p>Consider a physicist who wishes to predict a rocket&rsquo;s flight path. While a
&ldquo;rocket as a point&rdquo; representation is simple, it is also quite
inaccurate, failing to account for air friction, for example. In response,
the physicist may add the rocket&rsquo;s rough contour and introduce the
necessary mathematics to represent friction. This second model is a
<span style="font-style: italic">refinement</span> of the first model. In general, a scientist
repeats&#8212;<wbr></wbr>or as programmers say, <span style="font-style: italic">iterates</span>&#8212;<wbr></wbr>this process until
the model predicts the rocket&rsquo;s flight path with sufficient accuracy.</p><p>A programmer trained in a computer science department should proceed like this
physicist. The key is to find an accurate data representation of the real-world
information and functions that process them appropriately. Complicated situations
call for a refinement process to get to a sufficient data representation combined
with the proper functions. The process starts with the essential pieces of
information and adds others as needed. Sometimes a programmer must refine a model
<span style="font-weight: bold">after</span> the program has been deployed because users request additional
functionality.</p><p>So far we have used iterative refinement for you when it came to complex forms of
data. This chapter illustrates iterative refinement as a principle of program
development with an extended example, representing and processing (portions of) a
computer&rsquo;s file system. We start with a brief discussion of the file system and
then iteratively develop three data representations. Along the way, we propose
some programming exercises so that you see how the <a name="(idx._(gentag._517))"></a>design recipe also helps
modify existing programs.</p><h4>20.1<tt>&nbsp;</tt><a name="(part._sec~3afiles-what)"></a>Data Analysis</h4><p>Before you turn off DrRacket, you want to make sure that all your work is
safely stashed away somewhere. Otherwise you have to reenter
everything<span class="refelem"><span class="refcolumn"><span class="refcontent">A file is really a sequence of <span style="font-style: italic">bytes</span>,
one after another. Try to define the class of files.</span></span></span> when you fire up
DrRacket next. So you ask your computer to save programs and data in
<span style="font-style: italic">files</span>. A file is roughly a string.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_145.png" alt="image" width="376.759765625" height="308.6875"/></p></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aaccountant))" x-target-lift="Figure"></a>Figure&nbsp;123: </span>A sample directory tree</span></p></blockquote><p>On most computer systems, files are organized in <span style="font-style: italic">directories</span> or
<span style="font-style: italic">folders</span>. Roughly speaking, a directory contains some files and
some more directories. The latter are called sub-directories and may
contain yet more sub-directories and files. Because of the hierarchy, we
speak of <span style="font-style: italic">directory trees</span>.</p><p><a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">123</span></a> contains a graphical sketch of a small directory tree,
and the picture explains why computer scientists call them trees. Contrary
to convention in computer science, the figure shows the tree growing upward, with a root
directory named <span class="stt">TS</span>. The root directory contains one file, called <span class="stt">read!</span>,
and two sub-directories, called <span class="stt">Text</span> and <span class="stt">Libs</span>, respectively. The first
sub-directory, <span class="stt">Text</span>, contains only three files; the latter, <span class="stt">Libs</span>,
contains only two sub-directories, each of which contains at least one
file. Finally, each box has one of two annotations: a directory is annotated with
<span class="stt">DIR</span>, and a file is annotated with a number, its size.</p><p><a name="(counter._(exercise._ex~3adir0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;329. How many times does a file name <span class="stt">read!</span> occur in the
directory tree <span class="stt">TS</span>? Can you describe the path from the root directory to the
occurrences? What is the total size of all the files in the tree? What is the
total size of the directory if each directory node has size <span class="RktVal">1</span>? How many
levels of directories does it contain? <a href="part_four.html#%28counter._%28exercise._ex~3adir0%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>20.2<tt>&nbsp;</tt><a name="(part._sec~3afiles-models)"></a>Refining Data Definitions</h4><p><a href="part_four.html#%28counter._%28exercise._ex~3adir0%29%29" data-pltdoc="x">Exercise&nbsp;329</a> lists some of the questions that users routinely ask about
directories. To answer such questions, the computer&rsquo;s operating system provides
programs that can answer them. If you want to design such
programs, you need to develop a data representation for directory trees.</p><p>In this section, we use iterative refinement to develop three such data
representations. For each stage, we need to decide which attributes to include
and which to ignore. Consider the directory tree in <a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a>
and imagine how it is created. When a user first creates a directory, it is
empty. As time goes by, the user adds files and directories. In general, a user
refers to files by names but mostly thinks of directories as containers.</p><p><div class="SIntrapara"><span style="font-weight: bold">Model 1</span> Our thought experiment suggests that our first model should focus
on files as atomic entities with a name and directories as containers. Here is a
data definition that deals with directories as lists and files as strings,
that is, their names:
</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._dir..v1)"></a><span style="font-style: italic">Dir.v1</span><span class="RktCmt"> (short for </span><span style="font-style: italic">directory</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._file..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">File.v1</span></a><span class="stt"> </span><a href="part_four.html#%28tech._dir..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v1</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._dir..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v1</span></a><span class="stt"> </span><a href="part_four.html#%28tech._dir..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v1</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><span class="RktCmt">A </span><a name="(tech._file..v1)"></a><span style="font-style: italic">File.v1</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">. </span></td></tr></table></blockquote></div><div class="SIntrapara">The names have a <span style="font-style: italic">.v1</span> suffix to distinguish them from future refinements.</div></p><p><a name="(counter._(exercise._ex~3afile-example1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;330. Translate the directory tree in
<a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a> into a data representation according to model 1. <a href="part_four.html#%28counter._%28exercise._ex~3afile-example1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adir-how-many1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;331. Design the function <span class="RktSym">how-many</span>, which
determines how many files a given <a href="part_four.html#%28tech._dir..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v1</span></a> contains. Remember to follow the
design recipe; <a href="part_four.html#%28counter._%28exercise._ex~3afile-example1%29%29" data-pltdoc="x">exercise&nbsp;330</a> provides you with data examples. <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><span style="font-weight: bold">Model 2</span> If you solved <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many1%29%29" data-pltdoc="x">exercise&nbsp;331</a>, you know that this first
data definition is still reasonably simple. But, it also obscures the nature of
directories. With this first representation, we would not be able to list all the
names of the sub-directories of some given directory. To model directories in a
more faithful manner than containers, we must introduce a structure type that
combines a name with a container:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">dir</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">content</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">This new structure type, in turn, suggests the following revision of the data definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._dir..v2)"></a><span style="font-style: italic">Dir.v2</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-dir</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_four.html#%28tech._lofd%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOFD</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><span class="RktCmt">An </span><a name="(tech._lofd)"></a><span style="font-style: italic">LOFD</span><span class="RktCmt"> (short for </span><span style="font-style: italic">list of files and directories</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._file..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">File.v2</span></a><span class="stt"> </span><span class="RktSym">LOFD</span><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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._dir..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v2</span></a><span class="stt"> </span><a href="part_four.html#%28tech._lofd%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOFD</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><span class="RktCmt">A </span><a name="(tech._file..v2)"></a><span style="font-style: italic">File.v2</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">. </span></td></tr></table></blockquote></div><div class="SIntrapara">Note how the data definition for <a href="part_four.html#%28tech._dir..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v2</span></a> refers to the definition for
<a href="part_four.html#%28tech._lofd%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOFD</span></a>s, and the one for <a href="part_four.html#%28tech._lofd%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOFD</span></a>s refers back to that of <a href="part_four.html#%28tech._dir..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v2</span></a>.
The two definitions are mutually recursive.</div></p><p><a name="(counter._(exercise._ex~3afile-example2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;332. Translate the directory tree in
<a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a> into a data representation according to model 2. <a href="part_four.html#%28counter._%28exercise._ex~3afile-example2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adir-how-many2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;333. Design the function <span class="RktSym">how-many</span>, which
determines how many files a given <a href="part_four.html#%28tech._dir..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v2</span></a> contains.
<a href="part_four.html#%28counter._%28exercise._ex~3afile-example2%29%29" data-pltdoc="x">Exercise&nbsp;332</a> provides you with data examples. Compare your result
with that of <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many1%29%29" data-pltdoc="x">exercise&nbsp;331</a>. <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aalt-dir1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;334. Show how to equip a directory with two more attributes:
size and readability. The former measures how much space the directory itself (as
opposed to its content) consumes; the latter specifies whether
anyone else besides the user may browse the content of the directory. <a href="part_four.html#%28counter._%28exercise._ex~3aalt-dir1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><span style="font-weight: bold">Model 3</span> Like directories, files have attributes. To introduce these, we
proceed just as above. First, we define a structure for files:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">file</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">size</span><span class="hspace">&nbsp;</span><span class="RktSym">content</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Second, we provide a data definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._file..v3)"></a><span style="font-style: italic">File.v3</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-file</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As indicated by the field names, the string represents the name of the file, the
natural number its size, and the string its content.</div></p><p><div class="SIntrapara">Finally, let&rsquo;s split the <span class="RktSym">content</span> field of directories into two pieces: a
list of files and a list of sub-directories. This change requires a revision of
the structure type definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">dir.v3</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">dirs</span><span class="hspace">&nbsp;</span><span class="RktSym">files</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here is the refined data definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._dir..v3)"></a><span style="font-style: italic">Dir.v3</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-dir.v3</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_four.html#%28tech._dir%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir*</span></a><span class="stt"> </span><a href="part_four.html#%28tech._file%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">File*</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><span class="RktCmt">A </span><a name="(tech._dir*)"></a><span style="font-style: italic">Dir*</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a><span class="stt"> </span><a href="part_four.html#%28tech._dir%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir*</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><span class="RktCmt">A </span><a name="(tech._file*)"></a><span style="font-style: italic">File*</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._file..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">File.v3</span></a><span class="stt"> </span><a href="part_four.html#%28tech._file%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">File*</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Following a convention in computer science, the use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span> as the ending
of a name suggests &ldquo;many&rdquo; and is a marker distinguishing the name from similar
ones: <a href="part_four.html#%28tech._file..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">File.v3</span></a> and <a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a>.</div></p><p><a name="(counter._(exercise._ex~3afile-example3))"></a><span style="font-weight: bold">Exercise</span>&nbsp;335. Translate the directory tree in
<a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a> into a data representation according to model 3. Use
<span class="RktVal">""</span> for the content of files. <a href="part_four.html#%28counter._%28exercise._ex~3afile-example3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adir-how-many3))"></a><span style="font-weight: bold">Exercise</span>&nbsp;336. Design the function <span class="RktSym">how-many</span>, which
determines how many files a given <a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a> contains.
<a href="part_four.html#%28counter._%28exercise._ex~3afile-example3%29%29" data-pltdoc="x">Exercise&nbsp;335</a> provides you with data examples. Compare your result
with that of <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many2%29%29" data-pltdoc="x">exercise&nbsp;333</a>.</p><p>Given the complexity of the data definition, contemplate how anyone can
design correct functions. Why are you confident that <span class="RktSym">how-many</span>
produces correct results? <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adir-how-many-map))"></a><span style="font-weight: bold">Exercise</span>&nbsp;337. Use <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> to simplify the data
definition <a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a>. Then use ISL+&rsquo;s list-processing functions
from <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures&nbsp;<span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a> to simplify the
function definition(s) for the solution of <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many3%29%29" data-pltdoc="x">exercise&nbsp;336</a>. <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many-map%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Starting with a simple representation of the first model and refining it
step-by-step, we have developed a reasonably accurate data representation
for directory
trees. Indeed, this third data representation captures the nature of a directory
tree much more faithfully than the first two. Based on this model, we can create
a number of other functions that users expect from a computer&rsquo;s operating system.</p><h4>20.3<tt>&nbsp;</tt><a name="(part._sec~3arefine-funcs)"></a>Refining Functions</h4><p><div class="SIntrapara">To make the following exercises somewhat realistic, DrRacket comes
with<span class="refelem"><span class="refcolumn"><span class="refcontent">Add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktSym">htdp/dir</span><span class="RktPn">)</span> to the definitions area.</span></span></span> <span class="sroman">the <span class="Smaller"><span style="font-style: italic">dir.rkt</span></span> teachpack</span> from the first
edition of this book. This teachpack introduces the two structure type
definitions from model 3, though without the <span style="font-style: italic">.v3</span>
suffix. Furthermore, the teachpack provides a function that creates
representations of directory trees on your computer:<a name="(idx._(gentag._518))"></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._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">creates a representation of the </span><span class="stt">a-path</span><span class="RktCmt"> directory </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">create-dir</span><span class="hspace">&nbsp;</span><span class="RktSym">a-path</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></table></blockquote></div><div class="SIntrapara">For example, if you open DrRacket and enter the following three lines into the
definitions area:
</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">O</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">create-dir</span><span class="hspace">&nbsp;</span><span class="RktVal">"/Users/..."</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">on OS X </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">L</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">create-dir</span><span class="hspace">&nbsp;</span><span class="RktVal">"/var/log/"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">on Linux</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">W</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">create-dir</span><span class="hspace">&nbsp;</span><span class="RktVal">"C:\\Users\\..."</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">on Windows </span></td></tr></table></blockquote></div><div class="SIntrapara">you get data representations of directories on your computer after you
<span style="font-weight: bold">save</span> and then run the program. Indeed, you could use
<span class="RktSym">create-dir</span> to map the entire file system on your computer to an
instance of <a href="part_four.html#%28tech._dir..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dir.v3</span></a>.</div></p><p><span style="font-weight: bold">Warnings</span> (1) For large directory trees, DrRacket may need a lot of time
to build a representation. Use <span class="RktSym">create-dir</span> on small directory
trees first. (2) Do <span style="font-weight: bold">not</span> define your own <span style="font-style: italic">dir</span> structure
type. The teachpack already defines them, and you must not define a
structure type twice.</p><p>Although <span class="RktSym">create-dir</span> delivers only a representation of a directory tree,
it is sufficiently realistic to give you a sense of what it is like to design
programs at that level. The following exercises illustrate this point. They use
<span style="font-style: italic">Dir</span> to refer to the generic idea of a data representation for directory
trees. Use the simplest data definition of <span style="font-style: italic">Dir</span> that allows you to complete
the respective exercise. Feel free to use the data definition from
<a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many-map%29%29" data-pltdoc="x">exercise&nbsp;337</a> and the functions from
<a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures&nbsp;<span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>.</p><p><a name="(counter._(exercise._ex~3adir-how-many4))"></a><span style="font-weight: bold">Exercise</span>&nbsp;338. Use <span class="RktSym">create-dir</span> to turn some of your
directories into ISL+ data representations. Then use <span class="RktSym">how-many</span>
from <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many3%29%29" data-pltdoc="x">exercise&nbsp;336</a> to count how many files they contain. Why
are you confident that <span class="RktSym">how-many</span> produces correct results for
these directories? <a href="part_four.html#%28counter._%28exercise._ex~3adir-how-many4%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afile-find))"></a><span style="font-weight: bold">Exercise</span>&nbsp;339. Design <span class="RktSym">find?</span>. The function consumes a
<span style="font-style: italic">Dir</span> and a file name and determines whether or not a file with this name
occurs in the directory tree. <a href="part_four.html#%28counter._%28exercise._ex~3afile-find%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afile-ls))"></a><span style="font-weight: bold">Exercise</span>&nbsp;340. Design the function <span class="RktSym">ls</span>, which lists the names of
all files and directories in a given <span style="font-style: italic">Dir</span>. <a href="part_four.html#%28counter._%28exercise._ex~3afile-ls%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afile-du))"></a><span style="font-weight: bold">Exercise</span>&nbsp;341. Design <span class="RktSym">du</span>, a function that consumes a
<span style="font-style: italic">Dir</span> and computes the total size of all the files in the entire directory
tree. Assume that storing a directory in a <span style="font-style: italic">Dir</span> structure costs <span class="RktVal">1</span>
file storage unit. In the real world, a directory is basically a special file, and
its size depends on how large its associated directory is. <a href="part_four.html#%28counter._%28exercise._ex~3afile-du%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">The remaining exercises rely on the notion of a path, which for our purposes is a
list of names:
</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._path)"></a><span style="font-style: italic">Path</span><span class="RktCmt"> is [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">].</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> directions into a directory tree</span></td></tr></table></blockquote></div><div class="SIntrapara">Take a second look at <a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a>. In that diagram, the path from
<span class="stt">TS</span> to <span class="stt">part1</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="RktVal">"TS"</span><span class="stt"> </span><span class="RktVal">"Text"</span><span class="stt"> </span><span class="RktVal">"part1"</span><span class="RktPn">)</span>. Similarly,
the path from <span class="stt">TS</span> to <span class="stt">Code</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="RktVal">"TS"</span><span class="stt"> </span><span class="RktVal">"Libs"</span><span class="stt"> </span><span class="RktVal">"Code"</span><span class="RktPn">)</span>.</div></p><p><a name="(counter._(exercise._ex~3afile-find-path))"></a><span style="font-weight: bold">Exercise</span>&nbsp;342. Design <span class="RktSym">find</span>. The function consumes a
directory <span class="RktSym">d</span> and a file name <span class="RktSym">f</span>. If <span class="RktPn">(</span><span class="RktSym">find?</span><span class="stt"> </span><span class="RktSym">d</span><span class="stt"> </span><span class="RktSym">f</span><span class="RktPn">)</span> is <span class="RktVal">#true</span>,
<span class="RktSym">find</span> produces a path to a file with name <span class="RktSym">f</span>; otherwise it
produces <span class="RktVal">#false</span>.</p><p><span style="font-weight: bold">Hint</span> While it is tempting to first check whether the file name occurs in the
directory tree, you have to do so for every single sub-directory. Hence it is
better to combine the functionality of <span class="RktSym">find?</span> and <span class="RktSym">find</span>.</p><p><span style="font-weight: bold">Challenge</span> The <span class="RktSym">find</span> function discovers only one of the two files named
<span class="stt">read!</span> in <a href="part_four.html#%28counter._%28figure._fig~3aaccountant%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">123</span></a>. Design <span class="RktSym">find-all</span>, which
generalizes <span class="RktSym">find</span> and produces the list of all paths that lead to
<span class="RktSym">f</span> in <span class="RktSym">d</span>. What should <span class="RktSym">find-all</span> produce when
<span class="RktPn">(</span><span class="RktSym">find?</span><span class="stt"> </span><span class="RktSym">d</span><span class="stt"> </span><span class="RktSym">f</span><span class="RktPn">)</span> is <span class="RktVal">#false</span>? Is this part of the problem really a
challenge compared to the basic problem? <a href="part_four.html#%28counter._%28exercise._ex~3afile-find-path%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afile-ls-.R))"></a><span style="font-weight: bold">Exercise</span>&nbsp;343. Design the function <span class="RktSym">ls-R</span>, which lists the paths
to <span style="font-weight: bold">all</span> files contained in a given <span style="font-style: italic">Dir</span>. <a href="part_four.html#%28counter._%28exercise._ex~3afile-ls-.R%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afile-find-path-compose))"></a><span style="font-weight: bold">Exercise</span>&nbsp;344. Redesign <span class="RktSym">find-all</span> from
<a href="part_four.html#%28counter._%28exercise._ex~3afile-find-path%29%29" data-pltdoc="x">exercise&nbsp;342</a> using <span class="RktSym">ls-R</span> from <a href="part_four.html#%28counter._%28exercise._ex~3afile-ls-.R%29%29" data-pltdoc="x">exercise&nbsp;343</a>. This is
design by composition, and if you solved the challenge part of
<a href="part_four.html#%28counter._%28exercise._ex~3afile-find-path%29%29" data-pltdoc="x">exercise&nbsp;342</a> your new function can find directories, too. <a href="part_four.html#%28counter._%28exercise._ex~3afile-find-path-compose%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>21<tt>&nbsp;</tt><a name="(part._ch~3aevaluator)"></a>Refining Interpreters</h3><p>DrRacket is a program. It is a complex one, dealing with many different
kinds of data. Like most complex programs, DrRacket also consists of many
functions: one that allows programmers to edit text, another one that acts
like the interactions area, a third one that checks whether definitions and
expressions are &ldquo;grammatical,&rdquo; and so on.</p><p>In this chapter, we show you how to design the function that implements the
heart of the interactions area. Naturally, we use <a name="(idx._(gentag._519))"></a>iterative refinement for
this design project. As a matter of fact, the very idea of focusing on
this aspect of DrRacket is another instance of refinement, namely, the
obvious one of implementing only one piece of functionality.</p><p>Simply put, the interactions area performs the task of determining the
values of expressions that you enter. After you click <span class="emph">RUN</span>, the
interactions area knows about all the definitions. It is then ready to
accept an expression that may refer to these definitions, to determine the
value of this expression, and to repeat this cycle as often as you
wish. For this reason, many people also refer to the interactions area as
the <span style="font-style: italic">read-eval-print</span> loop, where <span style="font-style: italic">eval</span> is short for
<span style="font-style: italic">evaluator</span>, a function that is also called <span style="font-style: italic">interpreter</span>.</p><p>Like this book, our refinement process starts with numeric BSL
expressions. They are simple; they do not assume an understanding of
definitions; and even your sister in fifth grade can determine their
value. Once you understand this first step, you know the difference
between a BSL expression and its representation. Next we move on to
expressions with variables. The last step is to add definitions.</p><h4>21.1<tt>&nbsp;</tt><a name="(part._sec~3ainterpreter)"></a>Interpreting Expressions</h4><p>Our first task is to agree on a data representation for BSL programs.
That is, we must figure out how to represent a BSL expression as a
piece of BSL data. At first, this sounds strange and unusual, but it is
not difficult. Suppose we just want to represent numbers, additions, and
multiplications for a start. Clearly, numbers can stand for numbers. An
addition expression, however, calls for compound data because it contains
two expressions and because it is distinct from a multiplication
expression, which also needs a data representation.</p><p><div class="SIntrapara">Following <a href="part_one.html#%28part._ch~3astructure%29" data-pltdoc="x">Adding Structure</a>, a straightforward way to
represent additions and multiplications is to define two structure types,
each with two fields:
</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">add</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">mul</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The intention is that the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span> field contains one operand&#8212;<wbr></wbr>the
one to the &ldquo;left&rdquo; of the operator&#8212;<wbr></wbr>and the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span> field
contains the other operand. The following table shows three examples:</div></p><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">BSL expression</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">representation of BSL expression</span></p></td></tr><tr><td align="left"><span class="RktVal">3</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktVal">3</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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">300001</span><span class="hspace">&nbsp;</span><span class="RktVal">100000</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">300001</span><span class="hspace">&nbsp;</span><span class="RktVal">100000</span><span class="RktPn">)</span></td></tr></table></blockquote><p><div class="SIntrapara">The next question concerns an expression with sub-expressions:
</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._%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._%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="RktVal">3</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="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The surprisingly simple answer is that fields may contain any value. In
this particular case, <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span> may contain
representations of expressions, and you may nest this as deeply as you
wish. See <a href="part_four.html#%28counter._%28figure._fig~3arepresenting-bsl%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">124</span></a> for additional examples.</div></p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">BSL expression</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">representation of BSL expression</span></p></td></tr><tr><td align="left" valign="top"><span class="RktPn">(</span><span class="RktSym"><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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td><td align="left" valign="top"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left" valign="top"><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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._%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="RktVal">3</span><span class="RktPn">)</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._%2A%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="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">3</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 cla
representation of BSL expressions based on the structure type
definitions of <span class="RktSym">add</span> and <span class="RktSym">mul</span>. Let&rsquo;s use
<a name="(tech._bsl._expr)"></a><span style="font-style: italic">BSL-expr</span> in analogy for <a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> for the new class of
data.</p><p><div class="SIntrapara">Translate the following expressions into data:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span>0</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">33</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">3.14</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</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#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">3.14</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-9</span></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div></p><p><div class="SIntrapara">Interpret the following data as expressions:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-2</span></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-3</span></span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">33</span><span class="RktPn">)</span>
<span class="refelem"><span class="refcolumn"><span class="refcontent">Here &ldquo;interpret&rdquo; means &ldquo;translate
from data into information.&rdquo; In contrast, &ldquo;interpreter&rdquo; in the
title of this chapter refers to a program that consumes the representation
of a program and produces its value. While the two ideas are related, they
are not the same.</span></span></span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">3.14</span><span class="RktPn">)</span> <a href="part_four.html#%28counter._%28exercise._ex~3absl-dd%29%29" class="ex-end" data-pltdoc="x"></a></p></li></ol></div></p><p>Now that you have a data representation for BSL programs, it is time to
design an evaluator. This function consumes a representation of a BSL
expression and produces its value. Again, this function is unlike any you
have ever designed so it pays off to experiment with some examples. To
this end, either you can use the rules of arithmetic to figure out what
the value of an expression is or you can &ldquo;play&rdquo; in the interactions
area of DrRacket. Take a look at the following table for our examples:</p><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">BSL expression</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">its representation</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">its value</span></p></td></tr><tr><td align="left"><span class="RktVal">3</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktVal">3</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><span class="RktVal">3</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><span class="RktVal">2</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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="RktVal">10</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><span class="RktVal">30</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktP
values to which a representation of a BSL expression can evaluate. <a href="part_four.html#%28counter._%28exercise._ex~3absl-value%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-eval))"></a><span style="font-weight: bold">Exercise</span>&nbsp;347. Design <span class="RktSym">eval-expression</span>. The function
consumes a representation of a BSL expression and computes its value. <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-eval-bool))"></a><span style="font-weight: bold">Exercise</span>&nbsp;348. Develop a data representation for <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>
BSL expressions constructed from <span class="RktVal">#true</span>, <span class="RktVal">#false</span>,
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span>, 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._not%29%29" class="RktValLink" data-pltdoc="x">not</a></span>. Then design
<span class="RktSym">eval-bool-expression</span>, which consumes (representations of)
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> BSL expressions and computes their values. What kind of
values do these <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> expressions yield? <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-bool%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><span style="font-weight: bold">Convenience and parsing</span> S-expressions offer a convenient way to
represent BSL expressions in our programming language:
</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/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">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">2</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">+</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list '+ 1 1)</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><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._%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="RktVal">3</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="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">25</span></p></td></tr><tr><td><span class="stt">&gt; </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="hspace">&nbsp;</span><span class="RktVal">3</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">*</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list '+ (list '* 3 3) (list '* 4 4))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">By simply putting a quote in front of an expression, we get ISL+ data.</div></p><p>Interpreting an S-expression representation is clumsy, mostly because not
all S-expressions represent <a href="part_four.html#%28tech._bsl._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-expr</span></a>s. For example, <span class="RktVal">#true</span>,
<span class="RktVal">"hello"</span>, and <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">+</span><span class="stt"> </span><span class="RktVal">x</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktVal">)</span> are not representatives of
BSL expressions. As a result, S-expressions are quite inconvenient for
the designers of interpreters.</p><p>Programmers invented <span style="font-style: italic">parser</span>s to bridge the gap between convenience of
use and implementation. A parser simultaneously checks
whether some piece of data conforms to a data definition and, if it does,
builds a matching element from the chosen class of data. The latter is
called a <span style="font-style: italic">parse tree</span>. If the given data does not conform, a
parser signals an error, much like the checked functions from
<a href="part_one.html#%28part._sec~3ainput-errors%29" data-pltdoc="x">Input Errors</a>.</p><p><a href="part_four.html#%28counter._%28figure._fig~3aparse-bsl-expr%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">125</span></a> presents a BSL parser for
S-expressions. Specifically, <span class="RktSym">parse</span> consumes an
<a href="part_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a> and produces a <span class="RktSym">BSL-expr</span>&#8212;<wbr></wbr>if and only if the given
S-expression is the result of quoting a BSL expression that has a
<span class="RktSym">BSL-expr</span> representative.</p><p><a name="(counter._(exercise._ex~3absl-parse))"></a><span style="font-weight: bold">Exercise</span>&nbsp;349. Create tests for <span class="RktSym">parse</span> until DrRacket tells
you that every element in the definitions area is covered during the test
run. <a href="part_four.html#%28counter._%28exercise._ex~3absl-parse%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-parse2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;350. What is unusual about the definition of this
program with respect to the design recipe? <a href="part_four.html#%28counter._%28exercise._ex~3absl-parse2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-parse1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;351. Design <span class="RktSym">interpreter-expr</span>. The function
accepts S-expressions. If <span class="RktSym">parse</span> recognizes them as
<a href="part_four.html#%28tech._bsl._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-expr</span></a>, it produces their value. Otherwise, it signals the same
error as <span class="RktSym">parse</span>. <a href="part_four.html#%28counter._%28exercise._ex~3absl-parse1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(idx._(gentag._520))"></a>
<a name="(idx._(gentag._521))"></a>
<a name="(idx._(gentag._522))"></a></p><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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._bsl._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-expr</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">parse</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/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">atom?</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">parse-atom</span><span class="hspace">&nbsp;</span><span class="RktSym">s</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">parse-sl</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></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_four.html#%28tech._sl%29" class="techoutside" data-pltdoc="x"><span class="techinside">SL</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._bsl._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-expr</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">parse-sl</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/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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">consists-of-3</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"
not have a value if it contains a variable. Indeed, unless we know what
<span class="RktSym">x</span> stands for, it makes no sense to evaluate <span class="RktPn">(</span><span class="RktSym"><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="RktSym">x</span><span class="RktPn">)</span>. Hence, one first refinement of the evaluator is to add variables to
the expressions that we wish to evaluate. The assumption is that the
definitions area contains a definition such as
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">and that programmers evaluate expressions containing <span class="RktSym">x</span> in
the interactions area:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktSym">x</span></td></tr><tr><td><p><span class="RktRes">5</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><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">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">8</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><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">1/2</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">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">7.5</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Indeed, you could imagine a second definition, say
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktSym">y</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span>, and interactions that involve two variables:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">y</span><span class="hspace">&nbsp;</span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">34</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">The preceding section implicitly proposes symbols as representations for
variables. After all, if you were to choose quoted S-expressions to
represent expressions with variables, symbols would appear naturally:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">x</span></td></tr><tr><td><p><span class="RktRes">'x</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">*</span><span class="hspace">&nbsp;</span><span class="RktVal">1/2</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">*</span><span class="hspace">&nbsp;</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><p><span class="RktRes">(list '* 0.5 (list '* 'x 3))</span></p></td></tr></table></blockquote></div><div class="SIntrapara">One obvious alternative is a string, so that <span class="RktVal">"x"</span> would represent
<span class="RktSym">x</span>, but this book is not about designing interpreters, so we stick
with symbols. From this decision, it follows how to modify the data
definition from <a href="part_four.html#%28counter._%28exercise._ex~3absl-dd%29%29" data-pltdoc="x">exercise&nbsp;345</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">A </span><a name="(tech._bsl._var._expr)"></a><span style="font-style: italic">BSL-var-expr</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><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><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"> </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-add</span><span class="stt"> </span><a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a><span class="stt"> </span><a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</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">make-mul</span><span class="stt"> </span><a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a><span class="stt"> </span><a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We simply add one clause to the data definition.</div></p><p><div class="SIntrapara">As for data examples, the following table shows some BSL expressions
with variables and their <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> representation:
</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><span style="font-weight: bold">BSL expression</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">representation of BSL expression</span></p></td></tr><tr><td align="left"><span class="RktSym">x</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktVal">'</span><span class="RktVal">x</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-add</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td align="left"><span class="RktPn">(</span><span class="RktSym"><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">1/2</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">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="left"><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">1/2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-mul</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td align="left"><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._%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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">y</span><span class="hspace">&nbsp;</span><span clas
results when <span class="RktSym">x</span> is <span class="RktVal">5</span> and <span class="RktSym">y</span> <span class="RktVal">3</span>.</div></p><p>One way to determine the value of variable expressions is to replace all
variables with the values that they represent. This is the way you know
from mathematics classes in school, and it is a perfectly fine way.</p><p><a name="(counter._(exercise._ex~3absl-var-subst))"></a><span style="font-weight: bold">Exercise</span>&nbsp;352. Design <span class="RktSym">subst</span>. The function consumes a
<a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> <span class="RktSym">ex</span>, a <a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a> <span class="RktSym">x</span>, and a
<a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a> <span class="RktSym">v</span>. It produces a <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> like
<span class="RktSym">ex</span> with all occurrences of <span class="RktSym">x</span> replaced by <span class="RktSym">v</span>. <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-subst%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-var-numeric))"></a><span style="font-weight: bold">Exercise</span>&nbsp;353. Design the <span class="RktSym">numeric?</span> function. It
determines whether a <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> is also a <a href="part_four.html#%28tech._bsl._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-expr</span></a>. Here
we assume that your solution to <a href="part_four.html#%28counter._%28exercise._ex~3absl-dd%29%29" data-pltdoc="x">exercise&nbsp;345</a> is the definition for
<a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> without <a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a>s. <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-numeric%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-var-eval))"></a><span style="font-weight: bold">Exercise</span>&nbsp;354. Design <span class="RktSym">eval-variable</span>. The checked
function consumes a <span class="RktSym">BSL-var-expr</span> and determines its value if
<span class="RktSym">numeric?</span> yields true for the input. Otherwise it signals an
error.</p><p><div class="SIntrapara">In general, a program defines many constants in the definitions area, and
expressions contain more than one variable. To evaluate such expressions,
we need a representation of the definitions area when it contains a series
of constant definitions. For this exercise we use association lists:
</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">An </span><a name="(tech._al)"></a><span style="font-style: italic">AL</span><span class="RktCmt"> (short for </span><span style="font-style: italic">association list</span><span class="RktCmt">) is [</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_four.html#%28tech._association%29" class="techoutside" data-pltdoc="x"><span class="techinside">Association</span></a><span class="RktCmt">].</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._association)"></a><span style="font-style: italic">Association</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt">.</span></td></tr></table></blockquote></div><div class="SIntrapara">Make up elements of <a href="part_four.html#%28tech._al%29" class="techoutside" data-pltdoc="x"><span class="techinside">AL</span></a>.</div></p><p>Design <span class="RktSym">eval-variable*</span>. The function consumes a <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a>
<span class="RktSym">ex</span> and an association list <span class="RktSym">da</span>. Starting from
<span class="RktSym">ex</span>, it iteratively applies <span class="RktSym">subst</span> to all associations in
<span class="RktSym">da</span>. If <span class="RktSym">numeric?</span> holds for the result, it determines its
value; otherwise it signals the same error as <span class="RktSym">eval-variable</span>.
<span style="font-weight: bold">Hint</span> Think of the given <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a> as an atomic value and
traverse the given association list instead. We provide this hint because
the creation of this function requires a little design knowledge from
<a href="part_four.html#%28part._ch~3asimu%29" data-pltdoc="x">Simultaneous Processing</a>. <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span style="font-weight: bold">An environment model</span> <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval%29%29" data-pltdoc="x">Exercise&nbsp;354</a> relies on the
mathematical understanding of constant definitions. If a name is defined
to stand for some value, all occurrences of the name can be replaced with
the value. Substitution performs this replacement once and for all before
the evaluation process even starts.</p><p>An alternative approach, dubbed the <span style="font-style: italic">environment model</span>, is to look
up the value of a variable when needed. The evaluator starts processing
the expression immediately but also carries along the representation of
the definitions area. Every time the evaluator encounters a variable, it
looks in the definitions area for its value and uses it.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3absl-var-eval2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;355. Design <span class="RktSym">eval-var-lookup</span>. This
function has the same signature as <span class="RktSym">eval-variable*</span>:<a name="(idx._(gentag._523))"></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_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a><span class="RktCmt"> </span><a href="part_four.html#%28tech._al%29" class="techoutside" data-pltdoc="x"><span class="techinside">AL</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.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">eval-var-lookup</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">da</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></table></blockquote></div><div class="SIntrapara">Instead of using substitution, the function traverses the
expression in the manner that the design recipe for <a href="part_four.html#%28tech._bsl._var._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-var-expr</span></a>
suggests. As it descends the expression, it &ldquo;carries along&rdquo;
<span class="RktSym">da</span>. When it encounters a symbol <span class="RktSym">x</span>, it 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._assq%29%29" class="RktValLink" data-pltdoc="x">assq</a></span>
to look up the value of <span class="RktSym">x</span> in the association list. If there is no
value, <span class="RktSym">eval-var-lookup</span> signals an error. <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>21.3<tt>&nbsp;</tt><a name="(part._sec~3ainterpreter-functions)"></a>Interpreting Functions</h4><p>At this point, you understand how to evaluate BSL programs that consist
of constant definitions and variable expressions. Naturally you want to
add function definitions so that you know&#8212;<wbr></wbr>at least in principle&#8212;<wbr></wbr>how to
deal with all of BSL.</p><p>The goal of this section is to refine the evaluator of
<a href="part_four.html#%28part._sec~3ainterpreter-variables%29" data-pltdoc="x">Interpreting Variables</a> so that it can cope with
functions. Since function definitions show up in the definitions area,
another way to describe the refined evaluator is to say that it simulates
DrRacket when the definitions area contains a number of function definitions
and a programmer enters an expression in the interactions area that
contains uses of these functions.</p><p>For simplicity, let&rsquo;s assume that all functions in the definitions area
consume one argument and that there is only one such definition. The
necessary domain knowledge dates back to school where you learned that
<span style="font-style: italic">f</span>(<span style="font-style: italic">x</span>)<span style="font-style: italic"> = e</span> represents the definition of function <span style="font-style: italic">f</span>, that
<span style="font-style: italic">f</span>(<span style="font-style: italic">a</span>)<span style="font-style: italic"></span> represents the application of <span style="font-style: italic">f</span> to <span style="font-style: italic">a</span>, and that
to evaluate the latter, you substitute <span style="font-style: italic">a</span> for <span style="font-style: italic">x</span> in
<span style="font-style: italic">e</span>. As it turns out, the evaluation of function applications in a
language such as BSL works mostly like that, too.</p><p>Before tackling the following exercises, you may wish to refresh your
knowledge of the terminology concerning functions as presented in
intermezzo 1. Most of the time, algebra courses gloss over
this aspect of mathematics, but a precise use and understanding of
terminology is needed when you wish to solve these problems.</p><p><a name="(counter._(exercise._ex~3absl-one-def))"></a><span style="font-weight: bold">Exercise</span>&nbsp;356. Extend the data representation of
<a href="part_four.html#%28part._sec~3ainterpreter-variables%29" data-pltdoc="x">Interpreting Variables</a> to include the application of a
programmer-defined function. Recall that a function application consists
of two pieces: a name and an expression. The former is the name of the
function that is applied; the latter is the argument.</p><p>Represent these expressions: <span class="RktPn">(</span><span class="RktSym">k</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><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#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">k</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><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#%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="RktPn">(</span><span class="RktSym">i</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">k</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>. We refer to this newly defined
class of data as <a name="(tech._bsl._fun._expr)"></a><span style="font-style: italic">BSL-fun-expr</span>. <a href="part_four.html#%28counter._%28exercise._ex~3absl-one-def%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3absl-eval-def1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;357. Design <span class="RktSym">eval-definition1</span>. The
function consumes four arguments:
</div><div class="SIntrapara"><ol><li><p>a <a href="part_four.html#%28tech._bsl._fun._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-expr</span></a> <span class="RktSym">ex</span>;</p></li><li><p>a symbol <span class="RktSym">f</span>, which represents a function name;</p></li><li><p>a symbol <span class="RktSym">x</span>, which represents the functions&rsquo; parameter; and</p></li><li><p>a <a href="part_four.html#%28tech._bsl._fun._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-expr</span></a> <span class="RktSym">b</span>, which represents the function&rsquo;s body.</p></li></ol></div><div class="SIntrapara">It determines the value of <span class="RktSym">ex</span>. When <span class="RktSym">eval-definition1</span>
encounters an application of <span class="RktSym">f</span> to some argument, it
</div><div class="SIntrapara"><ol><li><p>evaluates the argument,</p></li><li><p>substitutes the value of the argument for <span class="RktSym">x</span> in <span class="RktSym">b</span>; and</p></li><li><p>finally evaluates the resulting expression with <span class="RktSym">eval-definition1</span>.</p></li></ol></div><div class="SIntrapara">Here is how to express the steps as code, assuming <span class="RktSym">arg</span> is the
argument of the function application:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace">&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">value</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">eval-definition1</span><span class="hspace">&nbsp;</span><span class="RktSym">arg</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">x</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">plugd</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">subst</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">value</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">eval-definition1</span><span class="hspace">&nbsp;</span><span class="RktSym">plugd</span><span class="hspace">&nbsp;</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Notice that this line uses a form of recursion that has not been
covered. The proper design of such functions is discussed in <a href="part_five.html" data-pltdoc="x">Generative Recursion</a>.</div></p><p>If <span class="RktSym">eval-definition1</span> encounters a variable, it signals the same
error as <span class="RktSym">eval-variable</span> from <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval%29%29" data-pltdoc="x">exercise&nbsp;354</a>. It also
signals an error for function applications that refer to a function name
other than <span class="RktSym">f</span>.</p><p><span style="font-weight: bold">Warning</span> The use of this uncovered form of recursion introduces a new
element into your computations: non-termination. That is, a program may
run forever instead of delivering a result or signaling an error. If you
followed the design recipes of the first four parts, you cannot write down
such programs. For fun, construct an input for <span class="RktSym">eval-definition1</span>
that causes it to run forever. Use <span class="emph">STOP</span> to terminate the
program. <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-def1%29%29" class="ex-end" data-pltdoc="x"></a></p><p>For an evaluator that mimics the interactions area, we need a representation
of the definitions area. We assume that it is a list of definitions.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3absl-prog-dd))"></a><span style="font-weight: bold">Exercise</span>&nbsp;358. Provide a structure type and a data
definition for function definitions. Recall that such a definition
has three essential attributes:
</div><div class="SIntrapara"><ol><li><p>the function&rsquo;s name, which is represented with a symbol;</p></li><li><p>the function&rsquo;s parameter, which is also a name; and</p></li><li><p>the function&rsquo;s body, which is a variable expression.</p></li></ol></div><div class="SIntrapara">We use <a name="(tech._bsl._fun._def)"></a><span style="font-style: italic">BSL-fun-def</span> to refer to this class of data.</div></p><p><div class="SIntrapara">Use your data definition to represent these BSL function definitions:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">g</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">h</span><span class="stt"> </span><span class="RktSym">v</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">v</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">g</span><span class="stt"> </span><span class="RktSym">v</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div></p><p>Next, define the class <a name="(tech._bsl._fun._def*)"></a><span style="font-style: italic">BSL-fun-def*</span> to represent a definitions area
that consists of a number of one-argument function definitions. Translate the
definitions area that defines <span class="RktSym">f</span>, <span class="RktSym">g</span>, and <span class="RktSym">h</span> into
your data representation and name it <span class="RktSym">da-fgh</span>.</p><p><div class="SIntrapara">Finally, work on the following wish:<a name="(idx._(gentag._524))"></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_four.html#%28tech._bsl._fun._def%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-def*</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_four.html#%28tech._bsl._fun._def%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-def</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retrieves the definition of </span><span class="RktSym">f</span><span class="RktCmt"> in </span><span class="RktSym">da</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">signals an error if there is none</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">lookup-def</span><span class="hspace">&nbsp;</span><span class="RktSym">da-fgh</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">g</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">g</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">lookup-def</span><span class="hspace">&nbsp;</span><span class="RktSym">da</span><span class="hspace">&nbsp;</span><span class="RktSym">f</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></table></blockquote></div><div class="SIntrapara">Looking up a definition is needed for the evaluation of applications. <a href="part_four.html#%28counter._%28exercise._ex~3absl-prog-dd%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3absl-eval-def))"></a><span style="font-weight: bold">Exercise</span>&nbsp;359. Design <span class="RktSym">eval-function*</span>. The function
consumes <span class="RktSym">ex</span>, a <a href="part_four.html#%28tech._bsl._fun._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-expr</span></a>, and <span class="RktSym">da</span>, a
<a href="part_four.html#%28tech._bsl._fun._def%2A%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-def*</span></a> representation of a definitions area. It produces the
result that DrRacket shows if you evaluate <span class="RktSym">ex</span> in the interactions
area, assuming the definitions area contains <span class="RktSym">da</span>.</p><p><div class="SIntrapara">The function works like <span class="RktSym">eval-definition1</span> from <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-def1%29%29" data-pltdoc="x">exercise&nbsp;357</a>.
For an application of some function <span class="RktSym">f</span>, it
</div><div class="SIntrapara"><ol><li><p>evaluates the argument;</p></li><li><p>looks up the definition of <span class="RktSym">f</span> in the <a href="part_four.html#%28tech._bsl._fun._def%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-fun-def</span></a>
representation of <span class="RktSym">da</span>, which comes with a parameter and a body;</p></li><li><p>substitutes the value of the argument for the function parameter in
the function&rsquo;s body; and</p></li><li><p>evaluates the new expression via recursion.</p></li></ol></div><div class="SIntrapara">Like DrRacket, <span class="RktSym">eval-function*</span> signals an error when it encounters a
variable or function name without definition in the definitions area. <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-def%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>21.4<tt>&nbsp;</tt><a name="(part._sec~3ainterpreter-all)"></a>Interpreting Everything</h4><p><div class="SIntrapara">Take a look at the following BSL program: <a name="(idx._(gentag._525))"></a> <a name="(idx._(gentag._526))"></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">close-to-pi</span><span class="hspace">&nbsp;</span><span class="RktVal">3.14</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">area-of-circle</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#%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">close-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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="hspace">&nbsp;</span><span class="RktSym">r</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.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">volume-of-10-cylinder</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#%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">10</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">area-of-circle</span><span class="hspace">&nbsp;</span><span class="RktSym">r</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Think of these definitions as the definitions area in DrRacket. After you
click <span class="emph">RUN</span>, you can evaluate expressions involving <span class="RktSym">close-to-pi</span>,
<span class="RktSym">area-of-circle</span>, and <span class="RktSym">volume-of-10-cylinder</span> in the
interactions area:
</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">area-of-circle</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#i3.14</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">volume-of-10-cylinder</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#i31.400000000000002</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><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="RktSym">close-to-pi</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#i9.42</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The goal of this section is to refine your evaluator again so that
it can mimic this much of DrRacket.</div></p><p><a name="(counter._(exercise._ex~3absl-da-all))"></a><span style="font-weight: bold">Exercise</span>&nbsp;360. Formulate a data definition for the
representation of DrRacket&rsquo;s definitions area. Concretely, the data
representation should work for a sequence that freely mixes constant
definitions and one-argument function definitions. Make sure you can
represent the definitions area consisting of three definitions at the
beginning of this section. We name this class of data
<a name="(tech._bsl._da._all)"></a><span style="font-style: italic">BSL-da-all</span>.</p><p>Design the function <span class="RktSym">lookup-con-def</span>. It consumes a
<a href="part_four.html#%28tech._bsl._da._all%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-da-all</span></a> <span class="RktSym">da</span> and a symbol <span class="RktSym">x</span>. It produces the
representation of a constant definition whose name is <span class="RktSym">x</span>, if such
a piece of data exists in <span class="RktSym">da</span>; otherwise the function signals an
error saying that no such constant definition can be found.</p><p>Design the function <span class="RktSym">lookup-fun-def</span>. It consumes a
<a href="part_four.html#%28tech._bsl._da._all%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSL-da-all</span></a> <span class="RktSym">da</span> and a symbol <span class="RktSym">f</span>. It produces the
representation of a function definition whose name is <span class="RktSym">f</span>, if such
a piece of data exists in <span class="RktSym">da</span>; otherwise the function signals an
error saying that no such function definition can be found. <a href="part_four.html#%28counter._%28exercise._ex~3absl-da-all%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-eval-all))"></a><span style="font-weight: bold">Exercise</span>&nbsp;361. Design <span class="RktSym">eval-all</span>. Like
<span class="RktSym">eval-function*</span> from <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-def%29%29" data-pltdoc="x">exercise&nbsp;359</a>, this function
consumes the representation of an expression and a definitions area. It
produces the same value that DrRacket shows if the expression is entered at
the prompt in the interactions area and the definitions area contains the
appropriate definitions. <span style="font-weight: bold">Hint</span> Your <span class="RktSym">eval-all</span> function should
process variables in the given expression like <span class="RktSym">eval-var-lookup</span> in
<a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval2%29%29" data-pltdoc="x">exercise&nbsp;355</a>. <a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-all%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-all-sexpr))"></a><span style="font-weight: bold">Exercise</span>&nbsp;362. It is cumbersome to enter the structure-based
data representation of BSL expressions and a definitions area. As
the end of <a href="part_four.html#%28part._sec~3ainterpreter%29" data-pltdoc="x">Interpreting Expressions</a> demonstrates, it is much easier to
quote expressions and (lists of) definitions.</p><p>Design a function <span class="RktSym">interpreter</span>. It consumes an <span class="RktSym">S-expr</span> and
an <span class="RktSym">Sl</span>. The former is supposed to represent an expression and the
latter a list of definitions. The function parses both with the
appropriate parsing functions and then uses <span class="RktSym">eval-all</span> from
<a href="part_four.html#%28counter._%28exercise._ex~3absl-eval-all%29%29" data-pltdoc="x">exercise&nbsp;361</a> to evaluate the expression. <span style="font-weight: bold">Hint</span> You must
adapt the ideas of <a href="part_four.html#%28counter._%28exercise._ex~3absl-parse2%29%29" data-pltdoc="x">exercise&nbsp;350</a> to create a parser for
definitions and lists of definitions. <a href="part_four.html#%28counter._%28exercise._ex~3absl-all-sexpr%29%29" class="ex-end" data-pltdoc="x"></a></p><p>At this point, you know a lot about interpreting BSL. Here are some of
the missing pieces: <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span>;
<a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s and such operations as <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-length%29%29" class="RktValLink" data-pltdoc="x">string-length</a></span> or
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span>; and lists with <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, <span class="RktSym"><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="RktSym"><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="RktSym"><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="RktSym"><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="RktSym"><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>; and so
on. Once your evaluator can cope with all these, it is basically complete
because your evaluators already know how to interpret recursive
functions. Now when we say &ldquo;trust us, you know how to design these
refinements,&rdquo; we mean it.</p><h3>22<tt>&nbsp;</tt><a name="(part._ch~3amoney-sexp)"></a>Project: The Commerce of XML</h3><p>XML is a widely used data language. One use concerns message exchanges
between programs running on different computers. For example, when you
point your web browser at a web site, you are connecting a program on your
computer to a program on another computer, and the latter sends XML data
to the former. Once the browser receives the XML data, it renders it as an
image on your computer&rsquo;s monitor.</p><p><div class="SIntrapara">The following comparison illustrates this idea with a concrete example:
</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><span style="font-weight: bold">XML data</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">rendered in a browser</span></p></td></tr><tr><td align="left" valign="bottom"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&lt;ul&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span><span class="stt">&lt;li&gt; hello &lt;/li&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span><span class="stt">&lt;li&gt; &lt;ul&gt; </span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">&lt;li&gt; one &lt;/li&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">&lt;li&gt; two &lt;/li&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">&lt;/ul&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span><span class="stt">&lt;/li&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span><span class="stt">&lt;li&gt; world &lt;/li&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span><span class="stt">&lt;li&gt; good bye &lt;/li&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/ul&gt;</span></p></td></tr></table></td><td align="left" valign="bottom"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" valign="bottom"><p><img src="xml-example.png" alt="" width="100" height="110"/></p></td></tr></table></blockquote></div><div class="SIntrapara">On the left, you see a piece of XML data that a web site may send to your
web browser. On the right, you see how one popular browser renders this
snippet graphically.</div></p><p>This chapter explains the basics of processing XML as another design
exercise concerning intertwined data definitions and <a name="(idx._(gentag._527))"></a>iterative
refinement. The next section starts with an informal comparison of
S-expressions and XML data and uses it to formulate a full-fledged
data<span class="refelem"><span class="refcolumn"><span class="refcontent">If you think XML is too
old-fashioned for 2022, feel free to redo the exercise for JSON or
some other modern data exchange format. The design principles remain the
same.</span></span></span> definition. The remaining sections explain with examples how to
process an S-expression of XML data.</p><h4>22.1<tt>&nbsp;</tt><a name="(part._sec~3axml)"></a>XML as S-expressions</h4><p><div class="SIntrapara">The most basic piece of XML data looks like this:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine&gt; &lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">It is called an <span style="font-style: italic">element</span> and &ldquo;machine&rdquo; is the name of the
element. The two parts of the element are like parentheses that delimit
the <span style="font-style: italic">content</span> of an element. When there is no content between the
two parts&#8212;<wbr></wbr>other than white space&#8212;<wbr></wbr>XML allows a short-hand:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine /&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">But, as far as we are concerned here, this short-hand is equivalent to
the explicitly bracketed version.</div></p><p><div class="SIntrapara">From an S-expression perspective, an XML element
is a <span style="font-weight: bold">named</span> pair of parentheses that surround some content.<span class="refelem"><span class="refcolumn"><span class="refcontent">Racket&rsquo;s
<span class="stt">xml</span> library represents XML with structures as well as S-expressions.</span></span></span> And
indeed, representing the above with an S-expression is quite natural:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">This piece of data has the opening and closing parentheses, and it comes
with space to embed content.</div></p><p><div class="SIntrapara">Here is a piece of XML data with content:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine&gt;&lt;action /&gt;&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Remember that the <span class="stt">&lt;action /&gt;</span> part is a short-hand, meaning we are
really looking at this piece of data:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine&gt;&lt;action&gt;&lt;/action&gt;&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">In general, the content of an XML element is a series of XML elements:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine&gt;&lt;action /&gt;&lt;action /&gt;&lt;action /&gt;&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Expand the short-hand for <span class="stt">&lt;action /&gt;</span> before you continue.</div></p><p><div class="SIntrapara">The S-expression representation continues to look simple. Here is the first
one:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">And this is the representation for the second one:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div></p><p><div class="SIntrapara">When you look at the piece of XML data with a sequence of three <span class="stt">&lt;action /&gt;</span>
elements as its content, you realize that you may wish to distinguish such
elements from each other. To this end, XML elements come with
<span style="font-style: italic">attributes</span>. For example,
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine initial="red"&gt;&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">is the &ldquo;machine&rdquo; element equipped with one attribute whose
<span style="font-style: italic">name</span> is &ldquo;initial&rdquo; and whose value is &ldquo;red&rdquo; between string
quotes. Here is a complex XML element with nested elements that have
attributes, too:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine initial="red"&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="red"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">next="green" /&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="green"</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">next="yellow" /&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="yellow" next="red" /&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">We use blanks, indentation, and line breaks to make the element readable,
but this white space has no meaning for our XML data here.</div></p><p><div class="SIntrapara">Naturally, S-expressions for these &ldquo;machine&rdquo; elements look much like
their XML cousins:<span class="refelem"><span class="refcolumn"><span class="refcontent">XML is 40 years younger than S-expressions.</span></span></span>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">To add attributes to an element, we use a list of lists where each of the
latter contains two items: a symbol and a string. The symbol represents
the name of the attribute and the string its value. This idea naturally
applies to complex forms of XML data, too:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"yellow"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"yellow"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr></table></blockquote></div><div class="SIntrapara">For now note how the attributes are marked by two opening
parentheses and the remaining list of (representations of) XML elements
has one opening parenthesis.</div></p><p>You may recall the idea from <a href="i2-3.html" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a>, which uses S-expressions to
represent XHTML, a special dialect of XML. In particular, the intermezzo
shows how easily a programmer can write down nontrivial XML data and even
templates of XML representations using <span class="RktSym">backquote</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._unquote%29%29" class="RktStxLink" data-pltdoc="x">unquote</a></span>. Of course, <a href="part_four.html#%28part._sec~3ainterpreter%29" data-pltdoc="x">Interpreting Expressions</a> points out that you
need a parser to determine whether any given S-expression is a
representation of XML data, and a parser is a complex and unusual kind of
function.</p><p><div class="SIntrapara">Nevertheless, we choose to go with a representation of XML based on
S-expressions to demonstrate the usefulness of this old, poetic idea in
practical terms. We proceed gradually to work out a data
definition, putting <a name="(idx._(gentag._528))"></a>iterative refinement to work. Here is a first attempt:
</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">An </span><a name="(tech._xexpr..v0)"></a><span style="font-style: italic">Xexpr.v0</span><span class="RktCmt"> (short for </span><span style="font-style: italic">X-expression</span><span class="RktCmt">) is a one-item list:</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </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">This is the &ldquo;named parentheses&rdquo; idea from the beginning of this
section. Equipping this element representation with content is easy:
</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">An </span><a name="(tech._xexpr..v1)"></a><span style="font-style: italic">Xexpr.v1</span><span class="RktCmt"> is a list:</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span class="RktPn">[</span><span class="RktSym">List-of</span><span class="stt"> </span><a href="part_four.html#%28tech._xexpr..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v1</span></a><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The symbolic name becomes the first item on a list that otherwise consists
of XML element representatives.</div></p><p><div class="SIntrapara">The last refinement step is to add attributes. Since the attributes in an
XML element are optional, the revised data definition has two clauses:
</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">An </span><a name="(tech._xexpr..v2)"></a><span style="font-style: italic">Xexpr.v2</span><span class="RktCmt"> is a list: </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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span style="font-style: italic">Body</span><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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">[</span><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_four.html#%28tech._attribute%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute</span></a><span class="RktPn">]</span><span class="stt"> </span><span style="font-style: italic">Body</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">where </span><span style="font-style: italic">Body</span><span class="RktCmt"> is short for [</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_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._attribute)"></a><span style="font-style: italic">Attribute</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> <
<a href="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</span></a>, but some are followed by a list of attributes and some by
just a list of <a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a>s. Reformulate the definition of
<a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a> to isolate the common beginning and highlight the different
kinds of endings.</p><p>Eliminate the use of <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> from <a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3axml-no-list-of%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3axml-represent))"></a><span style="font-weight: bold">Exercise</span>&nbsp;364. Represent this XML data as elements of <a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a>:
</div><div class="SIntrapara"><ol><li><p><span class="stt">&lt;transition from="seen-e" to="seen-f" /&gt;</span></p></li><li><p><span class="stt">&lt;ul&gt;&lt;li&gt;&lt;word /&gt;&lt;word /&gt;&lt;/li&gt;&lt;li&gt;&lt;word /&gt;&lt;/li&gt;&lt;/ul&gt;</span></p></li></ol></div><div class="SIntrapara">Which one could be represented in <a href="part_four.html#%28tech._xexpr..v0%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v0</span></a> or <a href="part_four.html#%28tech._xexpr..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v1</span></a>? <a href="part_four.html#%28counter._%28exercise._ex~3axml-represent%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3axml-interpret))"></a><span style="font-weight: bold">Exercise</span>&nbsp;365. Interpret the following elements of
<a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a> as XML data:
</div><div class="SIntrapara"><ol><li><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">server</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">name</span><span class="stt"> </span><span class="RktVal">"example.org"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></p></li><li><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">carcas</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">board</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">grass</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">player</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">name</span><span class="stt"> </span><span class="RktVal">"sam"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></p></li><li><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">start</span><span class="RktVal">)</span></p></li></ol></div><div class="SIntrapara">Which ones are elements of <a href="part_four.html#%28tech._xexpr..v0%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v0</span></a> or <a href="part_four.html#%28tech._xexpr..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v1</span></a>? <a href="part_four.html#%28counter._%28exercise._ex~3axml-interpret%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">Roughly speaking, X-expressions simulate structures via lists. The
simulation is convenient for programmers; it asks for the least amount of
keyboard typing. For example, if an X-expression does not come with an
attribute list, it is simply omitted. This choice of data representation
represents a trade-off between authoring such expressions manually and
processing them automatically. The best way to deal with the latter
problem is to provide functions that make X-expressions look like
structures, especially functions that access the quasi-fields:
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">xexpr-name</span>, which extracts the tag of the element representation;</p></li><li><p><span class="RktSym">xexpr-attr</span>, which extracts the list of attributes; and</p></li><li><p><span class="RktSym">xexpr-content</span>, which extracts the list of content elements.</p></li></ul></div><div class="SIntrapara">Once we have these functions, we can use lists to represent XML yet that act as
if they were instances of a structure type.</div></p><p><div class="SIntrapara">These functions parse S-expressions, and parsers are tricky to design. So
let&rsquo;s design them carefully, starting with some data examples:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">a0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"X"</span><span class="RktVal">)</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="RktSym">e0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</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">e1</span><span class="hspace">&nbsp;</span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym">a0</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">e2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</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">e3</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</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">e4</span><span class="hspace">&nbsp;</span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym">a0</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="RktVal">)</span><span class="
twice in the construction of X-expressions. The definition of <span class="RktSym">e0</span>
reminds us that an X-expression may not come with either attributes or
content. You should be able to explain why <span class="RktSym">e2</span> and <span class="RktSym">e3</span>
are basically equivalent.</div></p><p><div class="SIntrapara">Next we formulate a signature, a purpose statement, and a header: <a name="(idx._(gentag._529))"></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_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</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_four.html#%28tech._attribute%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retrieves the list of attributes of </span><span class="RktSym">xe</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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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></table></blockquote></div><div class="SIntrapara">Here we focus on <span class="RktSym">xexpr-attr</span>; we leave the other two as exercises.</div></p><p><div class="SIntrapara">Making up functional examples requires a decision concerning the extraction of
attributes from X-expressions without any. While our chosen representation completely
omits missing attributes, we must supply <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> for the
structure-based representation of XML. The function therefore produces
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> for such X-expressions:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">e0</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="RktPn">(</span><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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">e1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"X"</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._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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">e2</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="RktPn">(</span><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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">e3</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="RktPn">(</span><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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">e4</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"X"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">It is time to develop the template. Since the data definition for
<a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a> is complex, we proceed slowly, step-by-step. First, while the
data definition distinguishes two kinds of X-expressions, both clauses
describe data constructed by <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ing a symbol onto a
list. Second, what differentiates the two clauses is the rest of the list
and especially the optional presence of a list of attributes. Let&rsquo;s
translate these two insights into a 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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="RktSym">optional-loa+content</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">xe</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#%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;</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">optional-loa+content</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;</span><span class="RktPn">[</span><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="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">The local definition chops off the name of the X-expression and leaves the
remainder of the list, which may or may not start with a list of
attributes. The key is that it is just a list, and the two <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
clauses indicate so. Third, this list is <span style="font-weight: bold">not</span> defined via a
self-reference but as the optional <span class="RktSym"><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> of some attributes onto a
possibly empty list of X-expressions. In other words, we still need to
distinguish the two usual cases and extract the usual pieces:
</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">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="RktSym">optional-loa+content</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">xe</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#%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;</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">optional-loa+content</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;</span><span class="RktPn">[</span><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 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">optional-loa+content</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;</span><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%2
at hand. So, we switch to the fifth step of the design recipe. Clearly,
there are no attributes if the given X-expression comes with nothing but a
name. In the second clause, the question is whether the first item on the
list is a list of attributes or just an <a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a>. Because this
sounds complicated, we make a wish: <a name="(idx._(gentag._530))"></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._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_four.html#%28tech._attribute%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute</span></a><span class="RktCmt">] or </span><a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a><span class="RktCmt"> -&gt; ???</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">determines whether </span><span class="RktSym">x</span><span class="RktCmt"> is an element of [</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_four.html#%28tech._attribute%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktVal">#false</span><span class="RktCmt"> otherwise</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">list-of-attributes?</span><span class="hspace">&nbsp;</span><span class="RktSym">x</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">With this function, it is straightforward to finish <span class="RktSym">xexpr-attr</span>;
see <a href="part_four.html#%28counter._%28figure._fig~3axexpr-attr%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">126</span></a>. If the first item is a list of
attributes, the function produces it; otherwise there are no attributes.</div></p><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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="RktSym">optional-loa+content</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">xe</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#%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;</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">optional-loa+content</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;</span><span class="RktPn">[</span><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;</span><span class="RktPn">(</span><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">loa-or-x</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-
manner and get this definition:
</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._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_four.html#%28tech._attribute%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute</span></a><span class="RktCmt">] or </span><a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</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 </span><span class="RktSym">x</span><span class="RktCmt"> a list of attributes</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">list-of-attributes?</span><span class="hspace">&nbsp;</span><span class="RktSym">x</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">x</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></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">possible-attribute</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">x</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
unremarkable. What is <span style="font-weight: bold">remarkable</span> is the signature of this
function. Instead of specifying a single data definition as
possible inputs, the signature combines two data definitions separated
by the English word &ldquo;or.&rdquo; In ISL+ such an informal signature with a
definite meaning is acceptable on occasion.</div></p><p><a name="(counter._(exercise._ex~3axml-accessors))"></a><span style="font-weight: bold">Exercise</span>&nbsp;366. Design <span class="RktSym">xexpr-name</span> and
<span class="RktSym">xexpr-content</span>. <a href="part_four.html#%28counter._%28exercise._ex~3axml-accessors%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3axml-odd-recursion))"></a><span style="font-weight: bold">Exercise</span>&nbsp;367. The design recipe calls for a
self-reference in the template for <span class="RktSym">xexpr-attr</span>. Add this
self-reference to the template and then explain why the finished parsing
function does not contain it. <a href="part_four.html#%28counter._%28exercise._ex~3axml-odd-recursion%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3axml-dd))"></a><span style="font-weight: bold">Exercise</span>&nbsp;368. Formulate a data definition that replaces the
informal &ldquo;or&rdquo; signature for the definition of the
<span class="RktSym">list-of-attributes?</span> function. <a href="part_four.html#%28counter._%28exercise._ex~3axml-dd%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3alookup-attribute))"></a><span style="font-weight: bold">Exercise</span>&nbsp;369. Design <span class="RktSym">find-attr</span>. The
function consumes a list of attributes and a symbol. If the attributes
list associates the symbol with a string, the function retrieves this
string; otherwise it returns <span class="RktVal">#false</span>. Look up
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._assq%29%29" class="RktValLink" data-pltdoc="x">assq</a></span> and use it to define the function. <a href="part_four.html#%28counter._%28exercise._ex~3alookup-attribute%29%29" class="ex-end" data-pltdoc="x"></a></p><p>For the remainder of this chapter, <a name="(tech._xexpr)"></a><span style="font-style: italic">Xexpr</span> refers to
<a href="part_four.html#%28tech._xexpr..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v2</span></a>. Also, we assume <span class="RktSym">xexpr-name</span>, <span class="RktSym">xexpr-attr</span>,
and <span class="RktSym">xexpr-content</span> are defined. Finally, we use <span class="RktSym">find-attr</span>
from <a href="part_four.html#%28counter._%28exercise._ex~3alookup-attribute%29%29" data-pltdoc="x">exercise&nbsp;369</a> to retrieve attribute values.</p><h4>22.2<tt>&nbsp;</tt><a name="(part._sec~3aenum)"></a>Rendering XML Enumerations</h4><p>XML is actually a <span style="font-weight: bold">family</span> of languages. People define dialects for specific
channels of communication. For example, XHTML is the language for sending
web content in XML format. In this section, we illustrate how to design a
rendering function for a small snippet of XHTML, specifically the
enumerations from the beginning of this chapter.</p><p>The <span class="stt">ul</span> tag surrounds a so-called unordered HTML list. Each item of
this list is tagged with <span class="stt">li</span>, which tends to contain words but also
other elements, even enumerations. What &ldquo;unordered HTML&rdquo; means is that
each item is to be rendered with a leading bullet instead of a number.</p><p><div class="SIntrapara">Since <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> does not come with plain strings, it is not immediately
obvious how to represent XHTML enumerations in a subset. One option is to
refine the data representation one more time, so that an <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>
could be a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>. Another option is to introduce a representation
for text:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._xword)"></a><span style="font-style: italic">XWord</span><span class="RktCmt"> is </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">word</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">text</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktCmt">.</span></p></blockquote></div><div class="SIntrapara">Here, we use this second option; Racket, the language from which the
teaching languages are derived, offers teachpacks that include
<a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> in <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>.</div></p><p><a name="(counter._(exercise._ex~3axml-words))"></a><span style="font-weight: bold">Exercise</span>&nbsp;370. Make up three examples for <a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a>s. Design
<span class="RktSym">word?</span>, which checks whether some ISL+ value is in
<a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a>, and <span class="RktSym">word-text</span>, which extracts the value of the only
attribute of an instance of <a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3axml-words%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3axml+string))"></a><span style="font-weight: bold">Exercise</span>&nbsp;371. Refine the definition of <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> so that
you can represent XML elements, including items in enumerations, that are plain
strings. <a href="part_four.html#%28counter._%28exercise._ex~3axml%2Bstring%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Given the representation of words, representing an XHTML-style enumeration
of words is straightforward:
</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">An </span><a name="(tech._xenum..v1)"></a><span style="font-style: italic">XEnum.v1</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">ul</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_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a><span class="RktPn">]</span><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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">ul</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">Attributes</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_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a><span class="RktPn">]</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._xitem..v1)"></a><span style="font-style: italic">XItem.v1</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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">li</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><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/in
though they do not affect rendering.</div></p><p>Stop! Argue that every element of <a href="part_four.html#%28tech._xenum..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v1</span></a> is also in <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">XExpr</span></a>.</p><p><div class="SIntrapara">Here is a sample element of <a href="part_four.html#%28tech._xenum..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v1</span></a>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">e0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">ul</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">li</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">word</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">text</span><span class="hspace">&nbsp;</span><span class="RktVal">"one"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">li</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">word</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">text</span><span class="hspace">&nbsp;</span><span class="RktVal">"two"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It corresponds to the inner enumeration of the example from the beginning
of the chapter. Rendering it with help from <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/image</span></span> teachpack</span> should yield an image
like this:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -3.2265625px; margin: -3px -3px -3px -3px;" src="pict_146.png" alt="image" width="37.0654296875" height="38.15625"/></p></blockquote></div><div class="SIntrapara">The radius of the bullet and the distance between the bullet and the text
are matters of aesthetics; here the idea matters.</div></p><p><div class="SIntrapara">To create this kind of image, you might use this ISL+
program:<span class="refelem"><span class="refcolumn"><span class="refcontent">We developed these expressions in the interactions
area. What would <span style="font-style: italic">you</span> do?</span></span></span>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">e0-rendered</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._above%2Falign%29%29" class="RktValLink" data-pltdoc="x">above/align</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">left</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/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%2Falign%29%29" class="RktValLink" data-pltdoc="x">beside/align</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">center</span><span class="hspace">&nbsp;</span><span class="RktSym">BT</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._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"one"</span><span class="hspace">&nbsp;</span><span class="RktVal">12</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span><span class="RktPn">)</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/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%2Falign%29%29" class="RktValLink" data-pltdoc="x">beside/align</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">center</span><span class="hspace">&nbsp;</span><span class="RktSym">BT</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._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"two"</span><span class="hspace">&nbsp;</span><span class="RktVal">12</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">black</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="RktSym">BT</span> is a rendering of a bullet.</div></p><p>Now let&rsquo;s design the function carefully. Since the data representation
requires two data definitions, the design recipe tells you that you must
design two functions in parallel. A second look reveals, however, that in
this particular case the second data definition is disconnected from the
first one, meaning we can deal with it separately.</p><p><div class="SIntrapara">Furthermore, the definition for <a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a> consists of two
clauses, meaning the function itself should consist of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
with two clauses. The point of viewing <a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a> as a sub-language
of <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>, however, is to think of these two clauses in terms of
<a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> selector functions, in particular,
<span class="RktSym">xexpr-content</span>. With this function we can extract the textual part
of an item, regardless of whether it comes with attributes or not: <a name="(idx._(gentag._531))"></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_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</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">renders an item as a "word" prefixed by a bullet </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">render-item1</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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></table></blockquote></div><div class="SIntrapara">In general, <span class="RktSym">xexpr-content</span> extracts a list of <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>;
in this specific case, the list contains exactly one <a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a>,
and this word contains one text:
</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">render-item1</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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="RktSym">element</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">content</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="RktSym">a-word</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">word-text</span><span class="hspace">&nbsp;</span><span class="RktSym">element</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#%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-word</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">From here, it is straightforward:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">render-item1</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">i</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="RktSym">element</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">content</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="RktSym">a-word</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">word-text</span><span class="hspace">&nbsp;</span><span class="RktSym">element</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="RktSym">item</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._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace">&nbsp;</span><span class="RktSym">a-word</span><span class="hspace">&nbsp;</span><span class="RktVal">12</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">black</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
question of rendering it as text and equipping it with a leading bullet;
see the examples above for how you might discover this last step.</div></p><p><a name="(counter._(exercise._ex~3axml-item1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;372. Before you read on, equip the definition of
<span class="RktSym">render-item1</span> with tests. Make sure to formulate these tests in
such a way that they don&rsquo;t depend on the <span class="RktSym">BT</span> constant. Then explain
<span style="font-weight: bold">how</span> the function works; keep in mind that the purpose statement
explains <span style="font-weight: bold">what</span> it does. <a href="part_four.html#%28counter._%28exercise._ex~3axml-item1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Now we can focus on the design of a function that renders an
enumeration. Using the example from above, the first two design steps are
easy: <a name="(idx._(gentag._532))"></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_four.html#%28tech._xenum..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v1</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">renders a simple enumeration as an image </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">render-enum1</span><span class="hspace">&nbsp;</span><span class="RktSym">e0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">e0-rendered</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">render-enum1</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The key step is the development of a template. According to the data
definition, an element of <a href="part_four.html#%28tech._xenum..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v1</span></a> contains one interesting piece
of data, namely, the (representation of the) XML elements. The first item
is always <span class="RktVal">'</span><span class="RktVal">ul</span>, so there is no need to extract it, and the second,
optional item is a list of attributes, which we ignore. With this in mind, the
first template draft looks just like the one for <span class="RktSym">render-item1</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">render-enum1</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="hspace">&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_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a><span class="RktCmt">]</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">While the <a name="(idx._(gentag._533))"></a>data-oriented design recipe tells you that you should design a separate
function whenever you encounter a complex form of data, the
abstraction-based <a name="(idx._(gentag._534))"></a>design recipe from <a href="part_three.html" data-pltdoc="x">Abstraction</a> tells you to
reuse an existing abstraction, say, a list-processing function from
<a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list%29%29" data-pltdoc="x">figures&nbsp;<span class="FigureRef">95</span></a> and <a href="part_three.html#%28counter._%28figure._fig~3aisl-ho-list2%29%29" data-pltdoc="x"><span class="FigureRef">96</span></a>, when possible.
Given that <span class="RktSym">render-enum1</span> is supposed to process a
list and create a single image from it, the only two list-processing
abstractions whose signatures fit the bill are <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> and
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldl%29%29" class="RktValLink" data-pltdoc="x">foldl</a></span>. If you also study their purpose statements, you see a
pattern that is like the <span class="RktSym">e0-rendered</span> example above, especially
for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span>. Let&rsquo;s try to use it, following the reuse design
recipe:
</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">render-enum1</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</span><span class="RktPn">)</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#%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">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -&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="hspace">&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="RktPn">(</span><span class="RktSym">deal-with-one</span><span class="hspace">&nbsp;</span><span class="RktSym">item</span><span class="hspace">&nbsp;</span><span class="RktSym">so-far</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="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;</span><span class="RktPn">(</span><span class="RktSym"><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">deal-with-one</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span><span class="hspace">&nbsp;</span><span class="RktSym">content</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">From the type matching, you also know that:
</div><div class="SIntrapara"><ol><li><p>the first argument to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> must be a two-argument function;</p></li><li><p>the second argument must be an image; and</p></li><li><p>the last argument is the list representing XML content.</p></li></ol></div><div class="SIntrapara">Naturally <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-image%29%29" class="RktValLink" data-pltdoc="x">empty-image</a></span> is the correct starting point.</div></p><p><div class="SIntrapara">This design-by-reuse focuses our attention on the
function to be &ldquo;folded&rdquo; over the list. It turns one item and the image
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> has created so far into another image. The signature
for <span class="RktSym">deal-with-one</span> articulates this insight. Since the first
argument is an <a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a>, <span class="RktSym">render-item1</span> is the
function that renders it. This yields two images that must be combined:
the image of the first item and the image of the rest of the
items. To stack them, we use <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._above%29%29" class="RktValLink" data-pltdoc="x">above</a></span>: <a name="(idx._(gentag._535))"></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">render-enum1</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">xe</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> -&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="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">deal-with-one</span><span class="hspace">&nbsp;</span><span class="RktSym">item</span><span class="hspace">&nbsp;</span><span class="RktSym">so-far</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/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._above%2Falign%29%29" class="RktValLink" data-pltdoc="x">above/align</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">left</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">render-item1</span><span class="hspace">&nbsp;</span><span class="RktSym">item</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">so-far</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-interm
the full-fledged case. In the real world, web browsers must cope with
arbitrarily nested enumerations that arrive over the web. In XML and its
web browser dialect XHTML, nesting is straightforward. Any element may
show up as the content of any other element. To represent
this<span class="refelem"><span class="refcolumn"><span class="refcontent">Are you wondering whether arbitrary nesting is the
correct way to think about this problem? If so, develop a data definition
that allows only three levels of nesting and then use it.</span></span></span> relationship in our
limited XHTML representation, we say that an item is either a word or
another enumeration. <a href="part_four.html#%28counter._%28figure._fig~3axenum%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">127</span></a> displays the second revision
of the data definition. It includes a revision of the data definition for
enumerations so that the first definition refers to the correct form of
item.</p><blockquote class="Herefigure"><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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">SIZE</span><span class="hspace">&nbsp;</span><span class="RktVal">12</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">font size </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">COLOR</span><span class="hspace">&nbsp;</span><span class="RktVal">"black"</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">font color </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">BT</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">a graphical constant </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._beside%29%29" class="RktValLink" data-pltdoc="x">beside</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._circle%29%29" class="RktValLink" data-pltdoc="x">circle</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">solid</span><span class="hspace">&nbsp;</span><span class="RktSym">BLACK</span><span class="RktPn">)</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._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace">&nbsp;</span><span class="RktVal">" "</span><span class="hspace">&nbsp;</span><span class="RktSym">SIZE</span><span class="hspace">&nbsp;</span><span class="RktSym">COLOR</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._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</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">marks item with bullet</span><span class="hspace">&nbsp;&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">bulletize</span><span class="hspace">&nbsp;</span><span class="RktSym">item</span><span class="RktPn
rendering functions. Put differently, we need to revise
<span class="RktSym">render-enum1</span> and <span class="RktSym">render-item1</span> so that they can cope with
<a href="part_four.html#%28tech._xenum..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v2</span></a> and <a href="part_four.html#%28tech._xitem..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v2</span></a>, respectively. Software engineers face
these kinds of questions all the time, and it is another situation where
the <a name="(idx._(gentag._536))"></a>design recipe shines.</p><p><a href="part_four.html#%28counter._%28figure._fig~3aenum%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">128</span></a> shows the complete answer. Since the change is
confined to the data definitions for <a href="part_four.html#%28tech._xitem..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v2</span></a>, it should not come
as a surprise that the change to the rendering program shows up in the
function for rendering items. While <span class="RktSym">render-item1</span> does not need to
distinguish between different forms of <a href="part_four.html#%28tech._xitem..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v1</span></a>,
<span class="RktSym">render-item</span> is forced to use a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> because
<a href="part_four.html#%28tech._xitem..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v2</span></a> lists two different kinds of items. Given that this data
definition is close to one from the real world, the distinguishing
characteristic is not something simple&#8212;<wbr></wbr>like <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> vs
<span class="RktSym"><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>&#8212;<wbr></wbr>but a specific piece of the given item. If the item&rsquo;s
content is a <a href="part_four.html#%28tech._xword%29" class="techoutside" data-pltdoc="x"><span class="techinside">XWord</span></a>, the rendering function proceeds as before.
Otherwise, the item contains an enumeration, in which case
<span class="RktSym">render-item</span> uses <span class="RktSym">render-enum</span> to deal with the data,
because the data definition for <a href="part_four.html#%28tech._xitem..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v2</span></a> refers back to
<a href="part_four.html#%28tech._xenum..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v2</span></a> precisely at this point.<a name="(idx._(gentag._537))"></a></p><p><a name="(counter._(exercise._ex~3aenum2-test))"></a><span style="font-weight: bold">Exercise</span>&nbsp;373. <a href="part_four.html#%28counter._%28figure._fig~3aenum%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">128</span></a> is missing test
cases. Develop test cases for all the functions. <a href="part_four.html#%28counter._%28exercise._ex~3aenum2-test%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(idx._(gentag._538))"></a> <a name="(idx._(gentag._539))"></a></p><p><a name="(counter._(exercise._ex~3aenum2-design))"></a><span style="font-weight: bold">Exercise</span>&nbsp;374. The data definitions in <a href="part_four.html#%28counter._%28figure._fig~3axenum%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">127</span></a>
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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>. Rewrite them so they 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>. Then use the
recipe to design the rendering functions for <a href="part_four.html#%28tech._xenum..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v2</span></a> and
<a href="part_four.html#%28tech._xitem..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XItem.v2</span></a> from scratch. You should come up with the same definitions
as in <a href="part_four.html#%28counter._%28figure._fig~3aenum%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">128</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3aenum2-design%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aenum-refactor))"></a><span style="font-weight: bold">Exercise</span>&nbsp;375. The wrapping of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> with
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%2Falign%29%29" class="RktValLink" data-pltdoc="x">beside/align</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">center</span><span class="hspace">&nbsp;</span><span class="RktSym">BT</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></p></blockquote></div><div class="SIntrapara"> may surprise you. Edit the
function definition so that the wrap-around appears once in each clause.
Why are you confident that your change works? Which version do you prefer? <a href="part_four.html#%28counter._%28exercise._ex~3aenum-refactor%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3aenum-count))"></a><span style="font-weight: bold">Exercise</span>&nbsp;376. Design a program that counts all
<span class="RktVal">"hello"</span>s in an instance of <a href="part_four.html#%28tech._xenum..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v2</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3aenum-count%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aenum-subst))"></a><span style="font-weight: bold">Exercise</span>&nbsp;377. Design a program that replaces
all <span class="RktVal">"hello"</span>s with <span class="RktVal">"bye"</span> in an enumeration. <a href="part_four.html#%28counter._%28exercise._ex~3aenum-subst%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>22.3<tt>&nbsp;</tt><a name="(part._sec~3aconfig)"></a>Domain-Specific Languages</h4><p>Engineers routinely build large software systems that require a
configuration for specific contexts before they can be run. This
configuration task tends to fall to <span style="font-style: italic">systems administrators</span>
who must deal with many different software systems. The word
&ldquo;configuration&rdquo; refers to the data that the main function needs when
the program is launched at the command-line or via a gesture (mouse
click, swipe). In a sense a configuration is just an additional
argument, though it is usually so complex that program designers
prefer to handing it over via a file.</p><p>Since software engineers cannot assume that systems administrators know
every programming language, they tend to devise simple, special-purpose
configuration languages. These special languages are also known as
<span style="font-style: italic">domain-specific languages</span> (DSL).<span class="refelem"><span class="refcolumn"><span class="refcontent">Because
configurations abstract a program over various pieces of data, Paul
Hudak argued in the 1990s that DSLs are the <span style="font-weight: bold">ultimate abstractions</span>,
that is, that they generalize the ideas of <a href="part_three.html" data-pltdoc="x">Abstraction</a> to
perfection.</span></span></span> Developing these DSLs around a common core, say the
well-known XML syntax, simplifies life for systems administrators. They can
write small XML &ldquo;programs&rdquo; and thus configure the systems they must
launch.</p><p>While the construction of a DSL is often considered a task for an advanced
programmer, you are actually in a position already to understand, appreciate, and
implement a reasonably complex DSL. This section explains how it
all works. It first reacquaints you with finite state machines
(FSMs). Then it shows how to design, implement, and program a DSL
for configuring a system that simulates arbitrary FSMs.</p><p><span style="font-weight: bold">Finite State Machines Remembered</span> The theme of finite state machines
is an important one in computing, and this book has presented it several
times. Here we reuse the example from <a href="part_two.html#%28part._sec~3asec-fsm-list%29" data-pltdoc="x">Finite State Machines</a> as
the component for which we wish to design and implement a configuration
DSL.</p><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">An </span><span style="font-style: italic">FSM</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_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</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._1transition)"></a><span style="font-style: italic">1Transition</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><span style="font-style: italic">FSM-State</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> that specifies a color</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">data examples </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">fsm-traffic</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">"red"</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"green"</span><span class="hspace">&nbsp;</span><span class="RktVal">"yellow"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"yellow"</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</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._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktC
though reformulated using just lists and using the full power of ISL+.
The program consists of two data definitions, one data example, and two
function definitions: <span class="RktSym">simulate</span> and <span class="RktSym">find</span>. Unlike the
related programs in preceding chapters, this one represents a transition
as a list of two items: the current state and the next one. <a name="(idx._(gentag._540))"></a> <a name="(idx._(gentag._541))"></a></p><p>The main function, <span class="RktSym">simulate</span>, consumes a transition table and an
initial state; it then evaluates a <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span> expression, which
reacts to each key event with a state transition. The states are displayed
as colored squares. The <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span> clauses are
specified with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> expressions that consume the current state,
plus the actual key event, and that produce an image or the next state,
respectively.</p><p>As its signature shows, the auxiliary <span class="RktSym">find</span> function is completely
independent of the FSM application. It consumes a list of two-item lists
and an item, but the actual nature of the items is specified via
parameters. In the context of this program, <span class="RktCmt">X</span> and <span class="RktCmt">Y</span>
represent <a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a>s, meaning <span class="RktSym">find</span> consumes a transition
table together with a state and produces a state. The function body uses
the built-in <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._assoc%29%29" class="RktValLink" data-pltdoc="x">assoc</a></span> function to perform most of the work. Look up
the documentation 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._assoc%29%29" class="RktValLink" data-pltdoc="x">assoc</a></span> so that you understand why the body
of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> uses an <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> expression.</p><p><a name="(counter._(exercise._ex~3afsm-reacquaint1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;378. Modify the rendering function so that it
overlays the name of the state onto the colored square. <a href="part_four.html#%28counter._%28exercise._ex~3afsm-reacquaint1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afsm-reacquaint2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;379. Formulate test cases for <span class="RktSym">find</span>. <a href="part_four.html#%28counter._%28exercise._ex~3afsm-reacquaint2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3afsm-reacquaint3))"></a><span style="font-weight: bold">Exercise</span>&nbsp;380. Reformulate the data definition for
<a href="part_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</span></a> so that it is possible to restrict transitions to
certain keystrokes. Try to formulate the change so that <span class="RktSym">find</span>
continues to work without change. What else do you need to change to get
the complete program to work? Which part of the design recipe provides the
answer(s)? See <a href="part_two.html#%28counter._%28exercise._ex~3afsm-design3%29%29" data-pltdoc="x">exercise&nbsp;229</a> for the original exercise
statement. <a href="part_four.html#%28counter._%28exercise._ex~3afsm-reacquaint3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span style="font-weight: bold">Configurations</span> The FSM simulation function uses two arguments,
which jointly describe a machine. Rather than teach a potential
&ldquo;customer&rdquo; how to open an ISL+ program in DrRacket and launch a function
of two arguments, the &ldquo;seller&rdquo; of <span class="RktSym">simulate</span> may wish to
supplement this product with a configuration component.</p><p><div class="SIntrapara">A configuration component consists of two parts. The first one is a widely
used simple language that customers use to formulate the initial arguments
for a component&rsquo;s main function(s). The second one is a function that
translates what customers say into a function call for the main
function. For the FSM simulator, we must agree on how we represent finite
state machines in XML. By judicious planning, <a href="part_four.html#%28part._sec~3axml%29" data-pltdoc="x">XML as S-expressions</a> presents a
series of machine examples that look just right for the task. Recall the
final <span class="stt">machine</span> example in this section:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt">&lt;machine initial="red"&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="red"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">next="green" /&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="green"</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">next="yellow" /&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;action state="yellow" next="red" /&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/machine&gt;</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Compare it to the transition table <span class="RktSym">fsm-traffic</span> from
<a href="part_four.html#%28counter._%28figure._fig~3afsm-again%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">129</span></a>. Also recall the agreed-upon <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>
representation of this example:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">machine</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</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;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"green"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"yellow"</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;</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="hspace">&nbsp;</span><span class="RktVal">"yellow"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">next</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">What we are still lacking is a general data definition that describes all
possible <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> representations of <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>s:
</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">An </span><a name="(tech._xmachine)"></a><span style="font-style: italic">XMachine</span><span class="RktCmt"> is a nested list of this shape:</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">machine</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">initial</span><span class="stt"> </span><span class="RktRdr">,</span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;&nbsp;</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_four.html#%28tech._x1t%29" class="techoutside" data-pltdoc="x"><span class="techinside">X1T</span></a><span class="RktPn">]</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._x1t)"></a><span style="font-style: italic">X1T</span><span class="RktCmt"> is a nested list of this shape:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">action</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">state</span><span class="stt"> </span><span class="RktRdr">,</span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">next</span><span class="stt"> </span><span class="RktRdr">,</span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like <a href="part_four.html#%28tech._xenum..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">XEnum.v2</span></a>, <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a> describes a subset of all
<a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>. Thus, when we design functions that process this new form of
data, we may continue to use the generic <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> functions to access
pieces.</div></p><p><a name="(counter._(exercise._ex~3axmachine-data0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;381. The definitions of <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a> and
<a href="part_four.html#%28tech._x1t%29" class="techoutside" data-pltdoc="x"><span class="techinside">X1T</span></a> use quote, which is highly inappropriate for novice program
designers. Rewrite them first to 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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> and then <span class="RktSym"><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>. <a href="part_four.html#%28counter._%28exercise._ex~3axmachine-data0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3axmachine-data1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;382. Formulate an XML configuration for the BW machine,
which switches from white to black and back for every key event.
Translate the XML configuration into an <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a> representation. See
<a href="part_two.html#%28counter._%28exercise._ex~3afsm-design2%29%29" data-pltdoc="x">exercise&nbsp;227</a> for an implementation of the machine as a program. <a href="part_four.html#%28counter._%28exercise._ex~3axmachine-data1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Before we dive into the translation part of the configuration problem,
let&rsquo;s spell it out:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a program that uses an <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a> configuration
to run <span class="RktSym">simulate</span>.</p></blockquote></div><div class="SIntrapara">While this problem is specific to our case, it is easy to imagine a
generalization for similar systems, and we encourage you to do so.</div></p><p><div class="SIntrapara">The problem statement suggests a complete outline: <a name="(idx._(gentag._542))"></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_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">simulates an FSM via the given configuration </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">simulate-xmachine</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">simulate</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Following the problem statement, our function calls <span class="RktSym">simulate</span> with
two to-be-determined arguments. What we need to complete the definition
are two pieces: an initial state and a transition table. These two pieces
are part of <span class="RktSym">xm</span>, and we are best off wishing for appropriate
functions:
</div><div class="SIntrapara"><ul><li><p><div class="SIntrapara"><span class="RktSym">xm-state0</span> extracts the initial state from the given
<a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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">xm-state0</span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</span><span class="RktPn">)</span></p></blockquote></div></p></li><li><p><div class="SIntrapara"><span class="RktSym">xm-&gt;transitions</span> translates the embedded list of
<a href="part_four.html#%28tech._x1t%29" class="techoutside" data-pltdoc="x"><span class="techinside">X1T</span></a>s into a list of <a href="part_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</span></a>s:
</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">xm-&gt;transitions</span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">fsm-traffic</span><span class="RktPn">)</span></p></blockquote></div></p></li></ul></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._543))"></a>
<a name="(idx._(gentag._544))"></a>
<a name="(idx._(gentag._545))"></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_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">interprets the given configuration as a state machine </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">simulate-xmachine</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">simulate</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xm-state0</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xm-&gt;transitions</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</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_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a><span class="RktCmt"> -&gt; </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">extracts and translates the transition table from </span><span class="RktSym">xm0</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">xm-state0</span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"red"</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">xm-state0</span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">find-attr</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-attr</span><span class="hspace">&nbsp;</span><span class="RktSym">xm0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">initial</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">;</spa
<span class="RktSym">xm-state0</span> is straightforward. Given that the initial state is
specified as an attribute, <span class="RktSym">xm-state0</span> extracts the list of
attributes using <span class="RktSym">xexpr-attr</span> and then retrieves the value of
the <span class="RktVal">'</span><span class="RktVal">initial</span> attribute.</p><p><div class="SIntrapara">Let&rsquo;s then turn to <span class="RktSym">xm-&gt;transitions</span>, which translates the transitions
inside of an <span class="RktSym">XMachine</span> configuration into a transition table: <a name="(idx._(gentag._546))"></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_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</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_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">extracts &amp; translates the transition table from </span><span class="RktSym">xm</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">xm-&gt;transitions</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The name of the function prescribes the signature and suggests a purpose
statement. Our purpose statement describes a two-step process:
(1) extract the <span class="RktSym">Xexpr</span> representation of the transitions and (2)
translate them into an instance of [<a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> <a href="part_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</span></a>].</div></p><p><div class="SIntrapara">While the extraction part obviously uses <span class="RktSym">xexpr-content</span> to get the list,
the translation part calls for some more analysis. If you look back to the data
definition of <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a>, you see that the content of the <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a> is
a list of <a href="part_four.html#%28tech._x1t%29" class="techoutside" data-pltdoc="x"><span class="techinside">X1T</span></a>s. The signature tells us that the transition table is a
list of <a href="part_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</span></a>s. Indeed, it is quite obvious that each item in the
former list is translated into one item of the latter, which suggests a
use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span>: <a name="(idx._(gentag._547))"></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">xm-&gt;transitions</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</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_four.html#%28tech._x1t%29" class="techoutside" data-pltdoc="x"><span class="techinside">X1T</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._1transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">1Transition</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">xaction-&gt;action</span><span class="hspace">&nbsp;</span><span class="RktSym">xa</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;</span><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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace">&nbsp;</span><span class="RktSym">xaction-&gt;action</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">xexpr-content</span><span class="hspace">&nbsp;</span><span class="RktSym">xm</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As you can see, we follow the design ideas of
<a href="part_three.html#%28part._sec~3ausage-examples%29" data-pltdoc="x">Using Abstractions, by Example</a> and formulate the function as a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span>
whose body uses <span class="RktSym"><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>. Defining <span class="RktSym">xaction-&gt;action</span> is again
just a matter of extracting the appropriate values from an <a href="part_four.html#%28tech._xexpr%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr</span></a>.</div></p><p><a href="part_four.html#%28counter._%28figure._fig~3adsl%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">130</span></a> displays the complete solution. Here the translation
from the DSL to a proper function call is as large as the original
component. This is not the case for real-world systems; the DSL component
tends to be a small fraction of the overall product, which is why the
approach is so popular.</p><p><a name="(counter._(exercise._ex~3axmachine-data2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;383. Run the code in <a href="part_four.html#%28counter._%28figure._fig~3adsl%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">130</span></a> with
the BW Machine configuration from <a href="part_four.html#%28counter._%28exercise._ex~3axmachine-data1%29%29" data-pltdoc="x">exercise&nbsp;382</a>. <a href="part_four.html#%28counter._%28exercise._ex~3axmachine-data2%29%29" class="ex-end" data-pltdoc="x"></a></p><blockquote class="Herefigure"><blockquote class="Leftfigure"><blockquote class="FigureInside"><blockquote class="SubFlow"><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">machine-configuration.xml</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;machine initial="red"&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;</span><span class="stt">&lt;action state="red"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">next="green" /&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;</span><span class="stt">&lt;action state="green"</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">next="yellow" /&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;</span><span class="stt">&lt;action state="yellow" next="red" /&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;/machine&gt;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr></table></blockquote></blockquote></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3amachine-configuration..xml))" x-target-lift="Figure"></a>Figure&nbsp;131: </span>A file with a machine configuration</span></p></blockquote><h4>22.4<tt>&nbsp;</tt><a name="(part._sub~3areading-xml)"></a>Reading XML</h4><p><div class="SIntrapara">Systems administrators expect that sophisticated applications read
configuration programs<span class="refelem"><span class="refcolumn"><span class="refcontent">This section uses
<span class="sroman"><span class="Smaller"><span style="font-style: italic">2htdp/batch-io</span></span></span>
<span class="sroman"><span class="Smaller"><span style="font-style: italic">2htdp/universe</span></span></span>, and
<span class="sroman"><span class="Smaller"><span style="font-style: italic">2htdp/image</span></span></span> teachpacks.</span></span></span> from a file or
possibly from some place on the web. In ISL+ your programs can retrieve
(some) XML information. <a href="part_four.html#%28counter._%28figure._fig~3axexpr-tp%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">132</span></a> shows the relevant excerpt
from the teachpack. For consistency, the figure uses the suffix <span class="stt">.v3</span> for
its XML representation, including those data definitions for which there is
no version 2:
</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">An </span><a name="(tech._xexpr..v3)"></a><span style="font-style: italic">Xexpr.v3</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt"> </span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </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"> </span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt"> </span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt"> </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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._attribute%2A..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Attribute*.v3</span></a><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_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a><span class="RktPn">]</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"> </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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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="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_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._attribute*..v3)"></a><span style="font-style: italic">Attribute*.v3</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="techin
<a name="(idx._(gentag._549))"></a>
<a name="(idx._(gentag._550))"></a>
<a name="(idx._(gentag._551))"></a>
<a name="(idx._(gentag._552))"></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._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</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 </span><span class="RktSym">x</span><span class="RktCmt"> an </span><a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">effect</span><span class="RktCmt"> displays bad piece if </span><span class="RktSym">x</span><span class="RktCmt"> is not an </span><a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</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"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._xexpr~3f%29%29" class="RktValLink" data-pltdoc="x">xexpr?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</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;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">produces the first XML element in file </span><span class="RktSym">f</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-xexpr%29%29" class="RktValLink" data-pltdoc="x">read-xexpr</a></span><span class="hspace">&nbsp;</span><span class="RktSym">f</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;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</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>
<span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/batch-io</span></span> teachpack</span> is required, a program can read the element with
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-plain-xexpr%29%29" class="RktValLink" data-pltdoc="x">read-plain-xexpr</a></span>. The function retrieves the XML element in a
format that matches the <a href="part_four.html#%28tech._xmachine%29" class="techoutside" data-pltdoc="x"><span class="techinside">XMachine</span></a> data definition.
A function for retrieving XML elements from the web is also
available in the teachpack. Try this in DrRacket:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt;</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-plain-xexpr%2Fweb%29%29" class="RktValLink" data-pltdoc="x">read-plain-xexpr/web</a></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._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">"Https://Felleisen.org/"</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">"matthias/"</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">"HtDP2e/Files/machine-configuration.xml"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If your computer is connected to the web, this expression retrieves our
standard machine configuration.</div></p><p>Reading files or web pages introduces an entirely novel idea into our
computational model. As <a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a> explains, a BSL program is
evaluated in the same manner in which you evaluate variable expressions in
algebra. Function definitions are also treated just like in
algebra. Indeed, most algebra courses introduce conditional function
definitions, meaning <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> does not pose any challenges
either. Finally, while ISL+ introduces functions as values, the
evaluation model remains fundamentally the same.</p><p><div class="SIntrapara">One essential property of this computational model is that no matter how
often you call a function <span class="RktSym">f</span> on some argument(s) <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>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">f</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></p></blockquote></div><div class="SIntrapara">the answer remains the same. The introduction of <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>,
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-xexpr%29%29" class="RktValLink" data-pltdoc="x">read-xexpr</a></span>, and their relatives destroys this property,
however. The problem is that files and web sites may change over time so
that every time a program reads files or web sites it may get a new
result.</div></p><p>Consider the idea of looking up the stock price of a company. Point your
browser to <span class="stt">google.com/finance</span> or any other such financial web site and
enter the name of your favorite company, say, <span class="stt">Ford</span>. In response, the
site will display the current price of the company&rsquo;s stock and other
information&#8212;<wbr></wbr>for example, how much the price has changed since the last
time it was posted, the current time, and many other facts and ads.
The important point is that as you reload this page over the course of a
day or a week, some of the information on this web page will change.</p><p><div class="SIntrapara">An alternative to looking up such company information manually is to write
a small program that retrieves such information on a regular basis, say,
every 15 seconds. With ISL you can write a world program that performs
this task. You would launch it like this:
</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">stock-alert</span><span class="hspace">&nbsp;</span><span class="RktVal">"Ford"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">to see a world window that displays an image like the following:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_147.png" alt="image" width="316.0" height="51.0"/></p></blockquote></div></p><p><div class="SIntrapara">To develop such a program requires skills beyond normal program
design. First, you need to investigate how the web site formats its
information. In the case of Google&rsquo;s financial service page, an inspection
of the web source code shows the following pattern near the top:
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="Smaller"><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;meta content="17.09" itemprop="price" /&gt;</span></span></p></td></tr><tr><td><p><span class="Smaller"><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;meta content="+0.07" itemprop="priceChange" /&gt;</span></span></p></td></tr><tr><td><p><span class="Smaller"><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;meta content="0.41" itemprop="priceChangePercent" /&gt;</span></span></p></td></tr><tr><td><p><span class="Smaller"><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;meta content="2013-08-12T16:59:06Z" itemprop="quoteTime" /&gt;</span></span></p></td></tr><tr><td><p><span class="Smaller"><span class="hspace">&nbsp;&nbsp;</span><span class="stt">&lt;meta content="NYSE real-time data" itemprop="dataSource" /&gt;</span></span></p></td></tr></table></blockquote></div><div class="SIntrapara">If we had a function that could search an <a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a> and extract
(the representation of XML) <span class="stt">meta</span> elements with the attribute value
<span class="RktVal">"price"</span> and <span class="RktVal">"priceChange"</span>, the rest of
<span class="RktSym">stock-alert</span> would be straightforward.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._553))"></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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.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">PREFIX</span><span class="hspace">&nbsp;</span><span class="RktVal">"Https://www.google.com/finance?q="</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">SIZE</span><span class="hspace">&nbsp;</span><span class="RktVal">22</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">font size </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">data</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">price</span><span class="hspace">&nbsp;</span><span class="RktSym">delta</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._stockworld)"></a><span style="font-style: italic">StockWorld</span><span class="RktCmt"> is a structure: </span><span class="RktPn">(</span><span class="RktSym">make-data</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="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._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -&gt; </span><a href="part_four.html#%28tech._stockworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">StockWorld</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retrieves the stock price of </span><span class="RktSym">co</span><span class="RktCmt"> and its change every 15s</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">stock-alert</span><span class="hspace">&nbsp;</span><span class="RktSym">co</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="Rk
because the web service no longer delivers stock quotes.</span></span></span></p><p><a href="part_four.html#%28counter._%28figure._fig~3areal-time%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">133</span></a> displays the core of the program. The design of
<span class="RktSym">get</span> is left to the exercises because its workings are all about
intertwined data.</p><p>As the figure shows, the main function defines two local ones: a clock-tick
handler and a rendering function. The <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span> specification
requests that the clock tick every 15 seconds. When the clock ticks,
ISL+ applies <span class="RktSym">retrieve-stock-data</span> to the current world, which it
ignores. Instead, the function visits the web site via
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-xexpr%2Fweb%29%29" class="RktValLink" data-pltdoc="x">read-xexpr/web</a></span> and extracts the appropriate information with
<span class="RktSym">get</span>. Thus, the new world is created from newly available
information on the web, not some local data.</p><p><a name="(counter._(exercise._ex~3aweb-data0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;384. <a href="part_four.html#%28counter._%28figure._fig~3areal-time%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">133</span></a> mentions
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-xexpr%2Fweb%29%29" class="RktValLink" data-pltdoc="x">read-xexpr/web</a></span>. See
<a href="part_four.html#%28counter._%28figure._fig~3axexpr-tp%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">132</span></a> for its signature and purpose
statement and then read its documentation to determine
the difference to its &ldquo;plain&rdquo; relative.</p><p><a href="part_four.html#%28counter._%28figure._fig~3areal-time%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">133</span></a> is also missing several important pieces, in
particular the interpretation of <span class="RktSym">data</span> and purpose statements for
all the locally defined functions. Formulate the missing pieces so that
you get to understand the program. <a href="part_four.html#%28counter._%28exercise._ex~3aweb-data0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aweb-data1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;385. Look up the current stock price for your favorite
company at Google&rsquo;s financial service page. If you don&rsquo;t favor a company,
pick Ford. Then save the source code of the page as a file in your working
directory. Use <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-xexpr%29%29" class="RktValLink" data-pltdoc="x">read-xexpr</a></span> in DrRacket to view the source as an
<a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a>. <a href="part_four.html#%28counter._%28exercise._ex~3aweb-data1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aweb-data2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;386. Here is the <span class="RktSym">get</span> function: <a name="(idx._(gentag._554))"></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_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -&gt; </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retrieves the value of the </span><span class="RktVal">"content"</span><span class="RktMeta"></span><span class="RktCmt"> attribute </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">from a </span><span class="RktVal">'</span><span class="RktVal">meta</span><span class="RktCmt"> element that has attribute </span><span class="RktVal">"itemprop"</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">with value </span><span class="RktSym">s</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._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">get</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">meta</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">content</span><span class="hspace">&nbsp;</span><span class="RktVal">"+1"</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">itemprop</span><span class="hspace">&nbsp;</span><span class="RktVal">"F"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"F"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">"+1"</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">get</span><span class="hspace">&nbsp;</span><span class="RktSym">x</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/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">result</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">get-xexpr</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbs
an arbitrary <a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a> for the desired attribute and produces
[<a href="part_three.html#%28tech._sim-dd._maybe%29" class="techoutside" data-pltdoc="x"><span class="techinside">Maybe</span></a> <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>].</div></p><p>Formulate test cases that look for other values than <span class="RktVal">"F"</span> and that
force <span class="RktSym">get</span> to signal an error.</p><p>Design <span class="RktSym">get-xexpr</span>. Derive functional examples for this function
from those for <span class="RktSym">get</span>. Generalize these examples so that you are
confident <span class="RktSym">get-xexpr</span> can traverse an arbitrary
<a href="part_four.html#%28tech._xexpr..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Xexpr.v3</span></a>. Finally, formulate a test that uses the web data saved in
<a href="part_four.html#%28counter._%28exercise._ex~3aweb-data1%29%29" data-pltdoc="x">exercise&nbsp;385</a>. <a href="part_four.html#%28counter._%28exercise._ex~3aweb-data2%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>23<tt>&nbsp;</tt><a name="(part._ch~3asimu)"></a>Simultaneous Processing</h3><p>Some functions have to consume two arguments that belong to classes with
nontrivial data definitions. How to design such functions depends on
the relationship between the arguments. First, one of the arguments may
have to be treated as if it were atomic. Second, it is possible that the
function must process the two arguments in lockstep. Finally, the function
may process the given data in accordance to all possible cases. This
chapter illustrates the three cases with examples and provides an augmented
design recipe. The last section discusses the equality of compound data.</p><h4>23.1<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3acase1)"></a>Processing Two Lists Simultaneously: Case 1</h4><p><div class="SIntrapara">Consider the following signature, purpose statement, and header: <a name="(idx._(gentag._555))"></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._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&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">replaces the final </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> in </span><span class="RktSym">front</span><span class="RktCmt"> with </span><span class="RktSym">end</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">replace-eol-with</span><span class="hspace">&nbsp;</span><span class="RktSym">front</span><span class="hspace">&nbsp;</span><span class="RktSym">end</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">front</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The signature says that the function consumes two lists. Let&rsquo;s see how the
design recipe works in this case.</div></p><p><div class="SIntrapara">We start by working through examples. If the first argument is
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, <span class="RktSym">replace-eol-with</span> must produce the second
one, no matter what it is:
</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">replace-eol-with</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="RktVal">)</span><span class="RktPn">)</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="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">In contrast, if the first argument is not <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, the purpose
statement requires that we replace <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> at the end of
<span class="RktSym">front</span> with <span class="RktSym">end</span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">replace-eol-with</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">1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</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">a</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</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">replace-eol-with</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#%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">2</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">1</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">a</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</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-i
argument is a list, the function does not need to know anything about it.
By implication, its template should be that of a list-processing function with
respect to the first argument: <a name="(idx._(gentag._556))"></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">replace-eol-with</span><span class="hspace">&nbsp;</span><span class="RktSym">front</span><span class="hspace">&nbsp;</span><span class="RktSym">end</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">front</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">front</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">replace-eol-with</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">front</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">end</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">..
If <span class="RktSym">front</span> is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, <span class="RktSym">replace-eol-with</span> produces
<span class="RktSym">end</span>. If <span class="RktSym">front</span> is not <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, we must recall what
the template expressions compute:
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">front</span><span class="RktPn">)</span> evaluates to the first item on the list, and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">replace-eol-with</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">front</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">end</span><span class="RktPn">)</span> replaces the final
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</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._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">front</span><span class="RktPn">)</span> with <span class="RktSym">end</span>.</p></li></ul></div><div class="SIntrapara">Stop! Use the <a name="(idx._(gentag._557))"></a>table method to understand what these bullets mean for the
running example.</div></p><p><div class="SIntrapara">From here it is a small step to the complete definition: <a name="(idx._(gentag._558))"></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">replace-eol-with</span><span class="hspace">&nbsp;</span><span class="RktSym">front</span><span class="hspace">&nbsp;</span><span class="RktSym">end</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">front</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">end</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">front</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="RktPn">(</span><span class="RktSym">replace-eol-with</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">front</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">end</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><a name="(counter._(exercise._ex~3across))"></a><span style="font-weight: bold">Exercise</span>&nbsp;387. Design <span class="RktSym">cross</span>. The function consumes a list
of symbols and a list of numbers and produces all possible ordered pairs of
symbols and numbers. That is, when given <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">c</span><span class="RktVal">)</span> and <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span>, the expected result is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">c</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">(</span><span class="RktVal">c</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktVal">)</span><span class="RktVal">)</span>. <a href="part_four.html#%28counter._%28exercise._ex~3across%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>23.2<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3acase2)"></a>Processing Two Lists Simultaneously: Case 2</h4><p><a href="part_two.html#%28part._sec~3alist-produce%29" data-pltdoc="x">Functions that Produce Lists</a> presents the function <span class="RktSym">wages*</span>, which
computes the weekly wages of some workers given their work hours. It
consumes a list of numbers, which represents the hours worked per week, and
produces a list of numbers, which are the corresponding weekly wages. While the
problem assumes that all employees received the same pay rate, even a small
company pays its workers differentiated wages.</p><p><div class="SIntrapara">Here we look at a slightly more realistic version. The function now consumes
<span style="font-weight: bold">two</span> lists: the list of hours worked and the list of corresponding
hourly wages. We translate this revised problem into a revised header:<a name="(idx._(gentag._559))"></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._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&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">multiplies the corresponding items on </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktSym">hours</span><span class="RktCmt"> and </span><span class="RktSym">wages/h</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">assume</span><span class="RktCmt"> the two lists are of equal length </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">wages*.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">hours</span><span class="hspace">&nbsp;</span><span class="RktSym">wages/h</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></blockquote></div><div class="SIntrapara">Making up examples is straightforward:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._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">wages*.v2</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="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="RktPn">(</span><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">wages*.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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">5.65</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="RktVal">40</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#%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">226.0</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">wages*.v2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">5.65</span><span class="hspace">&nbsp;</span><span class="RktVal">8.75</span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">40.0</span><span class="hspace">&nbsp;</span><span class="RktVal">30.0</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">226.0</span><span class="hspace">&nbsp;</span><span class="RktVal">262.5</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As required, all three examples use lists of equal length.</div></p><p><div class="SIntrapara">The assumption concerning the inputs can also be exploited for the
development of the template. More concretely, the condition says that
<span class="RktPn">(</span><span class="RktSym"><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">hours</span><span class="RktPn">)</span> is true when <span class="RktPn">(</span><span class="RktSym"><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">wages/h</span><span class="RktPn">)</span> is true, and furthermore, <span class="RktPn">(</span><span class="RktSym"><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">hours</span><span class="RktPn">)</span> is true
when <span class="RktPn">(</span><span class="RktSym"><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">wages/h</span><span class="RktPn">)</span> is true. It is thus acceptable to
use a template for one of the two lists:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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">wages*.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">hours</span><span class="hspace">&nbsp;</span><span class="RktSym">wages/h</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">hours</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">hours</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"><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">wages/h</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">wages*.v2</span><span class="hspace">&nbsp;</span><span
<span class="RktSym">wages/h</span> are <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. Hence no selector expressions are
needed. In the second clause, both <span class="RktSym">hours</span> and <span class="RktSym">wages/h</span>
are <span class="RktSym">constructed</span> lists, which means we need four selector
expressions. Finally, because the last
two are lists of equal length, they make up a natural candidate for the
natural recursion of <span class="RktSym">wages*.v2</span>.</div></p><p>The only unusual aspect of this template is that the recursive application
consists of two expressions, both selector expressions for the two
arguments. But, this idea directly follows from the assumption.</p><p><div class="SIntrapara">From here, it is a short step to a complete function definition:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">wages*.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">hours</span><span class="hspace">&nbsp;</span><span class="RktSym">wages/h</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">hours</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#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">weekly-wage</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">hours</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._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">wages/h</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">wages*.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._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">hours</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"
clause is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. In the second one, we have three values
available:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">hours</span><span class="RktPn">)</span>, which represents the first number
of weekly hours;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">wages/h</span><span class="RktPn">)</span>, which is the first pay rate; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">wages*.v2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">hours</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._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">wages/h</span><span class="RktPn">)</span><span class="RktPn">)</span>, which, according
to the purpose statement, computes the list of weekly wages for the
remainders of the two lists.</p></li></ol></div><div class="SIntrapara">Now we just need to combine these values to get the final answer. As
suggested by the examples, we must compute the weekly wage for the first
employee and <span class="RktSym">construct</span> a list from that wage and the rest of the
wages:
</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._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">weekly-wage</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">hours</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._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">wages/h</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="RktPn">(</span><span class="RktSym">wages*.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._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">hours</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">wages/h</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The auxiliary function <span class="RktSym">weekly-wage</span> uses the number of hours
worked and the pay rate to compute the weekly wage for one worker:
<a name="(idx._(gentag._560))"></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._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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">computes the weekly wage from </span><span class="RktSym">pay-rate</span><span class="RktCmt"> and </span><span class="RktSym">hours</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">weekly-wage</span><span class="hspace">&nbsp;</span><span class="RktSym">pay-rate</span><span class="hspace">&nbsp;</span><span class="RktSym">hours</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._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">pay-rate</span><span class="hspace">&nbsp;</span><span class="RktSym">hours</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Which function do you need to use if you wish to compute the wages
for one worker? Which function do you need to change if you wish to
deal with income taxes?</div></p><p><a name="(counter._(exercise._ex~3aweekly-wage))"></a><span style="font-weight: bold">Exercise</span>&nbsp;388. In the real world, <span class="RktSym">wages*.v2</span> consumes
lists of employee structures and lists of work records. An employee
structure contains an employee&rsquo;s name, social security number, and pay
rate. A work record also contains an employee&rsquo;s name and the number of
hours worked in a week. The result is a list of structures that contain the
name of the employee and the weekly wage.</p><p>Modify the program in this section so that it works on these realistic
versions of data. Provide the necessary structure type definitions and data
definitions. Use the design recipe to guide the modification process. <a href="part_four.html#%28counter._%28exercise._ex~3aweekly-wage%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3azip))"></a><span style="font-weight: bold">Exercise</span>&nbsp;389. Design the <span class="RktSym">zip</span> function, which consumes a list
of names, represented as strings, and a list of phone numbers, also
strings. It combines those equally long lists into a list of phone records:
</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">phone-record</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace">&nbsp;</span><span class="RktSym">number</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._phonerecord)"></a><span style="font-style: italic">PhoneRecord</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-phone-record</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Assume that the corresponding list items belong to the same person. <a href="part_four.html#%28counter._%28exercise._ex~3azip%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>23.3<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3acase3)"></a>Processing Two Lists Simultaneously: Case 3</h4><p><div class="SIntrapara">Here is a third type of problem:
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Given a list of symbols <span class="RktSym">los</span> and a natural number
<span class="RktSym">n</span>, the function <span class="RktSym">list-pick</span> extracts the <span class="RktSym">n</span>th symbol
from <span class="RktSym">los</span>; if there is no such symbol, it signals an error.</p></blockquote></div><div class="SIntrapara">The question is how well the recipe works for the design of <span class="RktSym">list-pick</span>.</div></p><p><div class="SIntrapara">While the data definition for a list of symbols is fairly familiar by now,
recall the class of natural numbers from <a href="part_two.html#%28part._sec~3anats%29" data-pltdoc="x">Natural Numbers</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 style="font-style: italic">N</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">0</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._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span><span class="stt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Now we can proceed to the second step: <a name="(idx._(gentag._561))"></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._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">] </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="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">extracts the </span><span class="RktSym">n</span><span class="RktCmt">th symbol from </span><span class="RktSym">l</span><span class="RktCmt">; </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">signals an error if there is no such symbol</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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">l</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="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Both lists of symbols and natural numbers are classes with complex data
definitions. This combination makes the problem nonstandard, meaning we
must pay attention to every detail for every step of the design recipe.</div></p><p><div class="SIntrapara">At this point, we usually pick some input examples and figure out what the
desired output is. We start with inputs for which the function has to
work flawlessly: <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">c</span><span class="RktVal">)</span> and <span class="RktVal">2</span>. For a list of three
symbols and the index <span class="RktVal">2</span>, <span class="RktSym">list-pick</span> must return a
symbol. The question is whether it is <span class="RktVal">'</span><span class="RktVal">b</span> or <span class="RktVal">'</span><span class="RktVal">c</span>. In grade
school, you would have counted <span class="RktVal">1</span>, <span class="RktVal">2</span>, and picked
<span class="RktVal">'</span><span class="RktVal">b</span> without a first thought. But this is computer science, not
grade school. Here people start counting from <span class="RktVal">0</span>, meaning that
<span class="RktVal">'</span><span class="RktVal">c</span> is an equally appropriate choice. And indeed, this is the
choice we use:
</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">list-pick</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="RktVal">2</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">c</span><span class="RktPn">)</span></p></blockquote></div></p><p>Now that we have eliminated this fine point of <span class="RktSym">list-pick</span>, let&rsquo;s
look at the actual problem, the choice of inputs. The goal of the example
step is to cover the input space as much as possible. We do so by picking
one input per clause in the description of complex forms of data. Here this
procedure suggests we pick at least two elements from each class because
each data definition has two clauses. We choose <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> and
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> for the first argument, and <span class="RktVal">0</span> and
<span class="RktVal">3</span> for the latter. Two choices per argument means four examples
total; after all, there is no immediately obvious connection between the
two arguments and no restriction in the signature.</p><p><div class="SIntrapara">As it turns out, only one of these pairings produces a proper result; the
remaining ones choose a position that does not exist because the list
doesn&rsquo;t contain enough symbols:
</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-error%29%29" class="RktStxLink" data-pltdoc="x">check-error</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">list-pick</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">0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</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">list-pick</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">'</span><span class="RktVal">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="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-error%29%29" class="RktStxLink" data-pltdoc="x">check-error</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">list-pick</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">3</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The function is expected to signal an error, and we pick our favorite
message here.</div></p><p>Stop! Put these fragments into DrRacket&rsquo;s definitions area and run the partial
program.</p><p>The discussion on examples indicates that there are indeed four independent
cases that we must inspect for the design of the function. One way to
discover these cases is to arrange the conditions for each of the clauses
into a two-dimensional table:</p><p><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p></p></td><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td></tr><tr><td style="border-right: 1px solid black;"><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._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td></tr><tr><td style="border-right: 1px solid black;"><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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td></tr></table></blockquote></div><div class="SIntrapara">The horizontal dimension of the table lists those questions that
<span class="RktSym">list-pick</span> must ask about lists; the vertical dimension lists the
questions about natural numbers. By this arrangement, we naturally get four
squares, where each represents the case when both the
conditions on the horizontal and the vertical axis are true.</div></p><p><div class="SIntrapara">Our table suggests that 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> for the function template has
four clauses. We can figure out the appropriate condition for each of these
clauses by <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span>-ing the horizontal and vertical condition for each
box in the table:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p></p></td><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td></tr><tr><td style="border-right: 1px solid black;"><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._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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">l</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#%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">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</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;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediat
table into a conditional:
</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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">l</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._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="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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._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="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"><a href="https://docs.racket-l
possibilities and to focus on each individually as we add selector
expressions to each <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:</p><p><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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">l</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._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="RktPn">)</span></td></tr><tr><td><span class="hspace">&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></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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._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="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-l
<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 for non-empty lists contains two selector expressions.
The second argument, <span class="RktSym">n</span>, belongs to <a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a>, and the template&rsquo;s
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause for non-<span class="RktVal">0</span> numbers needs only one selector
expression. In those cases where either <span class="RktPn">(</span><span class="RktSym"><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">l</span><span class="RktPn">)</span> or <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> holds, the respective argument is atomic and there is no need for a
corresponding selector expression.</div></p><p><div class="SIntrapara">The final step of the template construction demands that we annotate the
template with recursions where the results of selector expressions belong
to the same class as the inputs. For this first example, we focus on the
last <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, which contains selector expressions for both
arguments. It is, however, unclear how to form the natural recursions. If
we disregard the purpose of the function, there are three possible recursions:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="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._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktSym">l</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._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Each one represents a feasible combination of the available expressions.
Since we cannot know which one matters or whether all three matter, we move
on to the next development stage.</div></p><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="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</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="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">extracts the </span><span class="RktSym">n</span><span class="RktCmt">th symbol from </span><span class="RktSym">l</span><span class="RktCmt">; </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">signals an error if there is no such symbol</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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">l</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._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="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#%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">'</span><span class="RktVal">list-pick</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-l
<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 in the template and decide what a proper answer is:
</div><div class="SIntrapara"><ol><li><p>If <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> holds, <span class="RktSym">list-pick</span> must
pick the first symbol from an empty list, which is impossible. The
answer must be an error signal.</p></li><li><p>If <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> holds, <span class="RktSym">list-pick</span> is
again asked to pick a symbol from an empty list.</p></li><li><p>If <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</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._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> holds, <span class="RktSym">list-pick</span> is
supposed to produce the first symbol from <span class="RktSym">l</span>. The selector expression
<span class="RktPn">(</span><span class="RktSym"><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> is the answer.</p></li><li><p><div class="SIntrapara">If <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">0</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._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> holds, we must analyze what the
available expressions compute. As we have seen, it is a good idea to work
through an existing example for this step. We pick a shortened variant of
the first example:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._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">list-pick</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="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">b</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here is what the three natural recursions compute with these values:
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">b</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> produces <span class="RktVal">'</span><span class="RktVal">b</span>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">b</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span> evaluates to <span class="RktVal">'</span><span class="RktVal">a</span>, the
wrong answer;</p></li><li><p>and <span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">b</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> signals an error.</p></li></ol></div><div class="SIntrapara">From this, we conclude that <span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="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._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="RktPn">)</span> computes
the desired answer in the last <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.</div></p></li></ol></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3atree-pick))"></a><span style="font-weight: bold">Exercise</span>&nbsp;390. Design the function <span class="RktSym">tree-pick</span>. The
function consumes a tree of symbols and a list of directions:
</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">branch</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></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">A </span><a name="(tech._to)"></a><span style="font-style: italic">TOS</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><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">make-branch</span><span class="stt"> </span><a href="part_four.html#%28tech._to%29" class="techoutside" data-pltdoc="x"><span class="techinside">TOS</span></a><span class="stt"> </span><a href="part_four.html#%28tech._to%29" class="techoutside" data-pltdoc="x"><span class="techinside">TOS</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><span class="RktCmt">A </span><a name="(tech._direction)"></a><span style="font-style: italic">Direction</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="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">'</a></span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="RktMeta"></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="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">'</a></span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._right%29%29" class="RktStxLink" data-pltdoc="x">right</a></span><span class="RktMeta"></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">A list of </span><a href="part_four.html#%28tech._direction%29" class="techoutside" data-pltdoc="x"><span class="techinside">Direction</span></a><span class="RktCmt">s is also called a path. </span></td></tr></table></blockquote></div><div class="SIntrapara">Clearly a <a href="part_four.html#%28tech._direction%29" class="techoutside" data-pltdoc="x"><span class="techinside">Direction</span></a> tells the fun
the right branch in a nonsymbolic tree. What is the result of the
<span class="RktSym">tree-pick</span> function? Don&rsquo;t forget to formulate a full signature.
The function signals an error when given a symbol and a non-empty path. <a href="part_four.html#%28counter._%28exercise._ex~3atree-pick%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>23.4<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3asimplify)"></a>Function Simplification</h4><p><div class="SIntrapara">The <span class="RktSym">list-pick</span> function in <a href="part_four.html#%28counter._%28figure._fig~3alist-pick%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">134</span></a> is far more
complicated than necessary. The first two <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses signal an
error. That is, if either
</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">or
</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">holds, the answer is an error. We can translate this observation into code:
</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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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;</span><span class="RktPn">(</span><span class="RktSym"><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">'</span><span class=
algebraic laws concerning Booleans:<span class="refelem"><span class="refcolumn"><span class="refcontent">These equations are known as
de Morgan&rsquo;s laws.</span></span></span>
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&nbsp;</span><span class="RktSym">bexp1</span><span class="hspace">&nbsp;</span><span class="RktSym">a-bexp</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&nbsp;</span><span class="RktSym">bexp2</span><span class="hspace">&nbsp;</span><span class="RktSym">a-bexp</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td valign="top"><p><span class="RktSym">==</span></p></td><td valign="top"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktSym">bexp1</span><span class="hspace">&nbsp;</span><span class="RktSym">bexp2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">a-bexp</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">A similar law applies when the sub-expressions 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._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span>s are
swapped. Applying these laws to <span class="RktSym">list-pick</span> yields this:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</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._or%29%29" class="RktStxLink" data-pltdoc="x">or</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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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._~3e%29%29" class="RktValLink" data-pltdoc="x">&gt;</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</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="RktPn">(</span><span class="RktSym"><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">alos</span><span class="RktPn">)</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#%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">'</span><span class="RktVal">list-pick</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&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" dat
because <span class="RktSym">n</span> belongs to <a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a>. Since <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="stt"> </span><span class="RktVal">#true</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span>
is equivalent to <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span>, we can rewrite the function again:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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">'</span><span class="RktVal">list-pick</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&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="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktVal">0</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~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-l
in <a href="part_four.html#%28counter._%28figure._fig~3alist-pick%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">134</span></a>, but we can do even better than this. Compare
the first condition in the latest version of <span class="RktSym">list-pick</span> with the
second and third. Since the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause filters out all
those cases when <span class="RktSym">alos</span> is empty, <span class="RktPn">(</span><span class="RktSym"><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">alos</span><span class="RktPn">)</span> in the last
two clauses is always going to evaluate to <span class="RktVal">#true</span>. If we replace
the condition with <span class="RktVal">#true</span> and simplify the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span> expressions
again, we get a three-line version of <span class="RktSym">list-pick</span></p><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="RktSym">list-pick</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="i2-3.html#%28tech._symbol%29" class="techoutside" data-pltdoc="x"><span class="techinside">Symbol</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;= 0] -&gt; </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">determines the </span><span class="RktSym">nth</span><span class="RktCmt"> symbol from </span><span class="RktSym">alos</span><span class="RktCmt">, counting from </span><span class="RktVal">0</span><span class="RktCmt">;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">signals an error if there is no </span><span class="RktSym">n</span><span class="RktCmt">th symbol</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">list-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">alos</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">'</span><span class="RktVal">list-pick</span><span class="hspace">&nbsp;</span><span class="RktVal">"list too short"</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"><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">0</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._first%29%29" class="RktValLin
<span class="RktSym">list-pick</span>. While it is far simpler than the original, it is
important to understand that we designed the original in a systematic
manner and that we were able to transform the first into the second with
well-established algebraic laws. We can therefore trust this simple
version. If we try to find the simple versions of functions directly, we
sooner or later fail to take care of a case in our analysis, and we are
guaranteed to produce flawed programs.</p><p><a name="(counter._(exercise._ex~3areplace-eol-simp))"></a><span style="font-weight: bold">Exercise</span>&nbsp;391. Design <span class="RktSym">replace-eol-with</span> using the
strategy of <a href="part_four.html#%28part._sec~3atwo-inputs~3acase3%29" data-pltdoc="x">Processing Two Lists Simultaneously: Case 3</a>. Start from the tests. Simplify
the result systematically. <a href="part_four.html#%28counter._%28exercise._ex~3areplace-eol-simp%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3atree-ref-simpl))"></a><span style="font-weight: bold">Exercise</span>&nbsp;392. Simplify the function <span class="RktSym">tree-pick</span>
from <a href="part_four.html#%28counter._%28exercise._ex~3atree-pick%29%29" data-pltdoc="x">exercise&nbsp;390</a>. <a href="part_four.html#%28counter._%28exercise._ex~3atree-ref-simpl%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>23.5<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3adesign)"></a>Designing Functions that Consume Two Complex Inputs</h4><p><div class="SIntrapara">The proper approach to designing functions of two (or more) complex
arguments is to follow the <a name="(idx._(gentag._562))"></a>general recipe. You must conduct a data
analysis and define the relevant classes of data. If the use of parametric
definitions such as <a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a> and short-hand examples such as <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">&amp;</span><span class="RktVal">)</span> confuses you, expand them so that the constructors become
explicit. Next you need a function signature and purpose. At this point,
you can think ahead and decide which of the following three situations you
are facing:
</div><div class="SIntrapara"><ol><li><p>If one of the parameters plays a dominant role, think of the other as
an atomic piece of data as far as the function is concerned.</p></li><li><p>In some cases the parameters range over the same class of values and
must have the same size. For example, two lists must have the same
length, or two web pages must have the same length and where one of them
contains an embedded page, the other one does, too. If the two parameters
have this equal status and the purpose suggests that they are processed in
a synchronized manner, you choose one parameter, organize the function
around it, and traverse the other in a parallel manner.</p></li><li><p>If there is no obvious connection between the two parameters, you
must analyze all possible cases with examples. Then use this analysis to
develop the template, especially the recursive parts.</p></li></ol></div></p><p><div class="SIntrapara">Once you decide that a function falls into the third category, develop a
two-dimensional table to make sure that no case falls through the
cracks. Let&rsquo;s use a nontrivial pair of data definitions to explain this
idea again:
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td align="left" valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><a name="(tech._lod)"></a><span style="font-style: italic">LOD</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_four.html#%28tech._direction%29" class="techoutside" data-pltdoc="x"><span class="techinside">Direction</span></a><span class="stt"> </span><a href="part_four.html#%28tech._lod%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOD</span></a><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace">&nbsp;</span></p></td><td align="left" valign="top"><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._tid)"></a><span style="font-style: italic">TID</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><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">make-binary</span><span class="stt"> </span><a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</span></a><span class="stt"> </span><a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</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">make-with</span><span class="stt"> </span><a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</span></a><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="stt"> </span><a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</span></a><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">The left data definition is the usual list definition; the right one
is a three-clause variant of <a href="part_four.html#%28tech._to%29" class="techoutside" data-pltdoc="x"><span class="techinside">TOS</span></a>. It uses two structure type 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">with</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">lft</span><span class="hspace">&nbsp;</span><span class="RktSym">info</span><span class="hspace">&nbsp;</span><span class="RktSym">rght</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-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">binary</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">lft</span><span class="hspace">&nbsp;</span><span class="RktSym">rght</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Assuming the function consumes an <a href="part_four.html#%28tech._lod%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOD</span></a> and a <a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</span></a>, the table
that you should come up with has this shape:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p></p></td><td style="border-bottom: 1px solid black;; border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><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._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> </p></td></tr><tr><td style="border-right: 1px solid black;"><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._symbol~3f%29%29" class="RktValLink" data-pltdoc="x">symbol?</a></span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td></tr><tr><td style="border-right: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym">binary?</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td></tr><tr><td style="border-right: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym">with?</span><span class="stt"> </span><span class="RktSym">t</span><span class="RktPn">)</span> </p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td><td><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td><p></p></td></tr></table></blockquote></div><div class="SIntrapara">Along the horizontal direction we enumerate the conditions that
recognize the sub-classes for the first parameter, here <a href="part_four.html#%28tech._lod%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOD</span></a>, and
along the vertical direction we enumerate the conditions for the second
parameter, <a href="part_four.html#%28tech._tid%29" class="techoutside" data-pltdoc="x"><span class="techinside">TID</span></a>.</div></p><p>The table guides the development of both the function examples and
the function template. As explained, the examples must cover all possible
cases; that is, there must be at least one example for each cell in the
table. Similarly, the template must have one <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 per
cell; its condition combines the horizontal and the vertical conditions in
an <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span> expression. Each <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, in turn, must
contain all feasible selector expressions for both parameters. If one of
the parameters is atomic, there is no need for a selector
expression. Finally, you need to be aware of the feasible natural
recursions. In general, all possible combinations of selector expressions
(and optionally, atomic arguments) are candidates for a natural
recursion. Because we can&rsquo;t know which ones are necessary and which ones
aren&rsquo;t, we keep them in mind for the coding step.</p><p>In summary, the design of multiparameter functions is just a variation on
the old design-recipe theme. The key idea is to translate the data
definitions into a table that shows all feasible and interesting
combinations. The development of function examples and the template
exploit the table as much as possible.</p><h4>23.6<tt>&nbsp;</tt><a name="(part._sec~3atwo-inputs~3aex)"></a>Finger Exercises: Two Inputs</h4><p><a name="(counter._(exercise._ex~3aset2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;393. <a href="part_two.html#%28counter._%28figure._fig~3asets-vs-lists%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">62</span></a> presents two data
definitions for finite sets. Design the <span class="RktSym">union</span> function for the
representation of finite sets of your choice. It consumes two sets and
produces one that contains the elements of both.</p><p>Design <span class="RktSym">intersect</span> for the same set representation. It consumes two
sets and produces the set of exactly those elements that occur in both. <a href="part_four.html#%28counter._%28exercise._ex~3aset2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3amerge))"></a><span style="font-weight: bold">Exercise</span>&nbsp;394. Design <span class="RktSym">merge</span>. The function consumes two
lists of numbers, sorted in ascending order. It produces a single sorted
list of numbers that contains all the numbers on both inputs lists. A
number occurs in the output as many times as it occurs on the two input
lists together. <a href="part_four.html#%28counter._%28exercise._ex~3amerge%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adrop-take))"></a><span style="font-weight: bold">Exercise</span>&nbsp;395. Design <span class="RktSym">take</span>. It consumes a list
<span class="RktSym">l</span> and a natural number <span class="RktSym">n</span>. It produces the first
<span class="RktSym">n</span> items from <span class="RktSym">l</span> or all of <span class="RktSym">l</span> if it is too short.</p><p>Design <span class="RktSym">drop</span>. It consumes a list <span class="RktSym">l</span> and a natural number
<span class="RktSym">n</span>. Its result is <span class="RktSym">l</span> with the first <span class="RktSym">n</span> items
removed or just &rsquo;<span class="RktPn">(</span><span class="RktPn">)</span> if <span class="RktSym">l</span> is too short. <a href="part_four.html#%28counter._%28exercise._ex~3adrop-take%29%29" class="ex-end" data-pltdoc="x"></a></p><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">An </span><a name="(tech._hm._word)"></a><span style="font-style: italic">HM-Word</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_two.html#%28tech._letter%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter</span></a><span class="RktCmt"> or </span><span class="RktVal">"_"</span><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><span class="RktVal">"_"</span><span class="RktCmt"> represents a letter to be guessed </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_four.html#%28tech._hm._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">HM-Word</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_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">runs a simplistic hangman game, produces the current state</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">play</span><span class="hspace">&nbsp;</span><span class="RktSym">the-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">time-limit</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="RktSym">the-word</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._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="hspace">&nbsp;</span><span class="RktSym">the-pick</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="RktSym">the-guess</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span
player picks a word, the other player gets told how many letters the word
contains. The latter picks a letter and asks the first player whether
and where this letter occurs in the chosen word. The game is over after an
agreed-upon time or number of rounds.</p><p><a href="part_four.html#%28counter._%28figure._fig~3ahangman-game%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">136</span></a> presents the essence of a time-limited
version of the game. See <a href="part_three.html#%28part._sec~3alocal-is-power%29" data-pltdoc="x">Local Definitions Add Expressive Power</a> for why
<span class="RktSym">checked-compare</span> is defined locally. <a name="(idx._(gentag._563))"></a></p><p>The goal of this exercise is to design <span class="RktSym">compare-word</span>, the central
function. It consumes the word to be guessed, a word <span class="RktSym">s</span> that
represents how much/little the guessing player has discovered, and the
current guess. The function produces <span class="RktSym">s</span> with all <span class="RktVal">"_"</span> where
the guess revealed a letter.</p><p><div class="SIntrapara">Once you have designed the function, run the program like this:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">LOCATION</span><span class="hspace">&nbsp;</span><span class="RktVal">"/usr/share/dict/words"</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">on OS X</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">AS-LIST</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-lines%29%29" class="RktValLink" data-pltdoc="x">read-lines</a></span><span class="hspace">&nbsp;</span><span class="RktSym">LOCATION</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">SIZE</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktSym">AS-LIST</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">play</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-ref%29%29" class="RktValLink" data-pltdoc="x">list-ref</a></span><span class="hspace">&nbsp;</span><span class="RktSym">AS-LIST</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._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace">&nbsp;</span><span class="RktSym">SIZE</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">See <a href="part_two.html#%28counter._%28figure._fig~3areading-a-dictionary%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">74</span></a> for an explanation. Enjoy and
refine as desired! <a href="part_four.html#%28counter._%28exercise._ex~3ahangman-list%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3awage-general))"></a><span style="font-weight: bold">Exercise</span>&nbsp;397. In a factory, employees punch time cards as
they arrive in the morning and leave in the evening. Electronic time cards
contain an employee number and record the number of hours worked per week.
Employee records always contain the name of the employee, an employee
number, and a pay rate.<a name="(idx._(gentag._564))"></a></p><p>Design <span class="RktSym">wages*.v3</span>. The function consumes a list of employee records
and a list of time-card records. It produces a list of wage records, which
contain the name and weekly wage of an employee. The function signals an
error if it cannot find an employee record for a time card or vice
versa.</p><p><span style="font-weight: bold">Assumption</span> There is at most one time card per employee number. <a href="part_four.html#%28counter._%28exercise._ex~3awage-general%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3apolyn))"></a><span style="font-weight: bold">Exercise</span>&nbsp;398. A linear combination is the sum of many linear terms,
that is, products of variables and numbers. The latter are called
coefficients in this context. Here are some examples:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><p><img src="pict_148.png" alt="image" width="22" height="8"/></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><img src="pict_149.png" alt="image" width="65" height="10"/></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><img src="pict_150.png" alt="image" width="102" height="10"/></p></td></tr></table></blockquote></div><div class="SIntrapara">In all examples, the coefficient of <span style="font-style: italic">x</span> is 5, that of
<span style="font-style: italic">y</span> is 17, and the one for <span style="font-style: italic">z</span> is 3.</div></p><p>If we are given values for variables, we can determine the value of a
polynomial. For example, if <span style="font-style: italic">x = </span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>, the value of <img src="pict_151.png" alt="image" width="22" height="8"/> is
<span style="font-style: italic"></span>5<span style="font-style: italic"></span>0<span style="font-style: italic"></span>; if <span style="font-style: italic">x = </span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span> and <span style="font-style: italic">y = </span>1<span style="font-style: italic"></span>, the value of <img src="pict_152.png" alt="image" width="65" height="10"/> is
<span style="font-style: italic"></span>6<span style="font-style: italic"></span>7<span style="font-style: italic"></span>; and if <span style="font-style: italic">x = </span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>, <span style="font-style: italic">y = </span>1<span style="font-style: italic"></span>, and <span style="font-style: italic">z = </span>2<span style="font-style: italic"></span>, the value
of <img src="pict_153.png" alt="image" width="102" height="10"/> is <span style="font-style: italic"></span>7<span style="font-style: italic"></span>3<span style="font-style: italic"></span>.</p><p><div class="SIntrapara">There are many different representations of linear combinations. We could,
for example, represent them with functions. An alternative representation is a
list of its coefficients. The above combinations would be represented as:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktVal">17</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">5</span><span class="hspace">&nbsp;</span><span class="RktVal">17</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This choice of representation assumes a fixed order of variables.</div></p><p>Design <span class="RktSym">value</span>. The function consumes two equally long lists: a
linear combination and a list of variable values. It produces the value of
the combination for these values. <a href="part_four.html#%28counter._%28exercise._ex~3apolyn%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aperm-xmas))"></a><span style="font-weight: bold">Exercise</span>&nbsp;399. Louise, Jane, Laura, Dana, and Mary decide to run
a lottery that assigns one gift recipient to each of them. Since Jane is a
developer, they ask her to write a program that performs this task in an
impartial manner. Of course, the program must not assign any of the sisters
to herself.</p><p><div class="SIntrapara">Here is the core of Jane&rsquo;s program: <a name="(idx._(gentag._565))"></a> <a name="(idx._(gentag._566))"></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._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] -&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._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">picks a random non-identity arrangement of </span><span class="RktSym">names</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">gift-pick</span><span class="hspace">&nbsp;</span><span class="RktSym">names</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">random-pick</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">non-same</span><span class="hspace">&nbsp;</span><span class="RktSym">names</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace">&nbsp;</span><span class="RktSym">names</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">[</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] -&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_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">returns all possible permutations of </span><span class="RktSym">names</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">see </span><a href="part_two.html#%28counter._%28exercise._ex~3apermutations%29%29" data-pltdoc="x">exercise&nbsp;213</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">arrangements</span><span class="hspace">&nbsp;</span><span class="RktSym">names</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._
that do not agree with the original list at any place.</div></p><p><div class="SIntrapara">Your task is to design two auxiliary functions: <a name="(idx._(gentag._567))"></a> <a name="(idx._(gentag._568))"></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"> X] -&gt; X </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">returns a random item from the list </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">random-pick</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._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;</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._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">] [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">]] </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">-&gt; </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_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">]]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">produces the list of those lists in </span><span class="RktSym">ll</span><span class="RktCmt"> that do </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">not agree with </span><span class="RktSym">names</span><span class="RktCmt"> at any place </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">non-same</span><span class="hspace">&nbsp;</span><span class="RktSym">names</span><span class="hspace">&nbsp;</span><span class="RktSym">ll</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><spa
function takes two arguments, both lists of <span class="RktVal">'</span><span class="RktVal">a</span>, <span class="RktVal">'</span><span class="RktVal">c</span>,
<span class="RktVal">'</span><span class="RktVal">g</span>, and <span class="RktVal">'</span><span class="RktVal">t</span>, symbols that occur in DNA descriptions. The
first list is called a pattern, the second one a search string. The
function returns <span class="RktVal">#true</span> if the pattern is identical to the initial
part of the search string; otherwise it returns <span class="RktVal">#false</span>.</p><p>Also design <span class="RktSym">DNAdelta</span>. This function is like <span class="RktSym">DNAprefix</span> but
returns the first item in the search string beyond the pattern. If the
lists are identical and there is no DNA letter beyond the pattern, the
function signals an error. If the pattern does not match the beginning of
the search string, it returns <span class="RktVal">#false</span>. The function must
not traverse either of the lists more than once.</p><p>Can <span class="RktSym">DNAprefix</span> or <span class="RktSym">DNAdelta</span> be simplified? <a href="part_four.html#%28counter._%28exercise._ex~3adna-prefix%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3atest-compare))"></a><span style="font-weight: bold">Exercise</span>&nbsp;401. Design <span class="RktSym">sexp=?</span>, a function that
determines whether two S-expressions are equal. For convenience,
here is the data definition in condensed form:
</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">An </span><span style="font-style: italic">S-expr</span><span class="RktCmt"> (S-expression) 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><a href="part_four.html#%28tech._atom%29" class="techoutside" data-pltdoc="x"><span class="techinside">Atom</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</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_four.html#%28tech._s._expr%29" class="techoutside" data-pltdoc="x"><span class="techinside">S-expr</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">An </span><span style="font-style: italic">Atom</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><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">&ndash;</span><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"> </span></td></tr></table></blockquote></div></p><p>Whenever you use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span>, it uses a function like
<span class="RktSym">sexp=?</span> to check whether the two arbitrary values are equal. If
not, the check fails 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._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> reports it as such. <a href="part_four.html#%28counter._%28exercise._ex~3atest-compare%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3absl-var-eval-atomic))"></a><span style="font-weight: bold">Exercise</span>&nbsp;402. Reread <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval%29%29" data-pltdoc="x">exercise&nbsp;354</a>.
Explain the reasoning behind our hint to think of the given
expression as an atomic value at first. <a href="part_four.html#%28counter._%28exercise._ex~3absl-var-eval-atomic%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>23.7<tt>&nbsp;</tt><a name="(part._db._sec~3aproj-db)"></a>Project: Database</h4><p>Many software applications use a database to keep track of data. Roughly
speaking, a database is a table that comes with an explicitly stated
organization rule. The former is the <span style="font-style: italic">content</span>; the latter
is<span class="refelem"><span class="refcolumn"><span class="refcontent">This section pulls together knowledge from all four parts
of the book.</span></span></span> called a <span style="font-style: italic">schema</span>. <a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">137</span></a> shows
two examples. Each table consists of two parts: the schema above the line
and the content below.</p><p><div class="SIntrapara">Let&rsquo;s focus on the table on the left. It has three columns and four
rows. Each column comes with a two-part rule:
</div><div class="SIntrapara"><ol><li><p>the rule in the left-most column says that the label of the column
is &ldquo;Name&rdquo; and that every piece of data in this column is a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>;</p></li><li><p>the middle column is labeled &ldquo;Age&rdquo; and contains <a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a>s; and</p></li><li><p>the label of the right-most one is &ldquo;Present&rdquo;; its values are
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>.</p></li></ol></div><div class="SIntrapara">Stop! Explain the table on the right in the same way.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td valign="top"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Age</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Present</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr></table></td><td valign="top"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="top" style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td valign="top" style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Present</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Description</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="p
schema introduces terminology to refer to columns of a relation and to
individual cells in a row. Each row relates a fixed number of values; the
collection of all rows makes up the entire relation. In this terminology,
the first row of the left table in <a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a> relates
<span class="RktVal">"Alice"</span> to <span class="RktVal">35</span> and <span class="RktVal">#true</span>. Furthermore, the first
cell of a row is called the &ldquo;Name&rdquo; cell, the second the &ldquo;Age&rdquo; cell,
and the third one the &ldquo;Present&rdquo; cell.</p><p><div class="SIntrapara">In this section, we represent databases via structures and lists:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">schema</span><span class="hspace">&nbsp;</span><span class="RktSym">content</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._db._db)"></a><span style="font-style: italic">DB</span><span class="RktCmt"> is a structure: </span><span class="RktPn">(</span><span class="RktSym">make-db</span><span class="stt"> </span><a href="part_four.html#%28tech._db._schema%29" class="techoutside" data-pltdoc="x"><span class="techinside">Schema</span></a><span class="stt"> </span><a href="part_four.html#%28tech._db._content%29" class="techoutside" data-pltdoc="x"><span class="techinside">Content</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><span class="RktCmt">A </span><a name="(tech._db._schema)"></a><span style="font-style: italic">Schema</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_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</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._db._spec)"></a><span style="font-style: italic">Spec</span><span class="RktCmt"> is a [</span><a href="part_three.html#%28tech._sim-dd._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">List</span></a><span class="RktCmt"> </span><a href="part_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a><span class="RktCmt"> </span><a href="part_four.html#%28tech._db._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">Predicate</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._db._label)"></a><span style="font-style: italic">Label</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A </span><a name="(tech._db._predicate)"></a><span style="font-style: italic">Predicate</span><span class="RktCmt"> is a [</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_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">A (piece of) </span><a name="(tech._db._content)"></a><span style="font-style: italic">Content</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_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</s
chosen data representation. Note that the content of the tables already
uses ISL+ data.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">school-schema</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">"Name"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><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~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Age"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._integer~3f%29%29" class="RktValLink" data-pltdoc="x">integer?</a></span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Present"</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace">&nbsp;</span></p></td><td valign="top" style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td valign="top" style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">presence-schema</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">"Present"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Description"</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><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~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td valign="top"><p></p></td><td valign="top"><p><span class="hspace">&nbsp;</span></p
<a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a> as <a href="part_four.html#%28tech._db._db%29" class="techoutside" data-pltdoc="x"><span class="techinside">DB</span></a>s. Its left-hand side represents
the schema, the content, and the database from the left-hand side
table in <a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a>; its right part corresponds to the
right-hand side table. For succinctness, the examples use 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._quasiquote%29%29" class="RktStxLink" data-pltdoc="x">quasiquote</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._unquote%29%29" class="RktStxLink" data-pltdoc="x">unquote</a></span> notation. Recall that it allows
the inclusion of a value such as <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span> in an otherwise
quoted list. If you feel uncomfortable with this
notation, reformulate these examples 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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>.</p><p><a name="(counter._db._(exercise._ex~3adb-choice-of-rep))"></a><span style="font-weight: bold">Exercise</span>&nbsp;403. A <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> combines a <a href="part_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a> and
a <a href="part_four.html#%28tech._db._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">Predicate</span></a> into a list. While acceptable, this choice violates our
guideline of using a structure type for a fixed number of pieces of
information.</p><p><div class="SIntrapara">Here is an alternative data representation:
</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">spec</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">label</span><span class="hspace">&nbsp;</span><span class="RktSym">predicate</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">Spec is a structure: </span><span class="RktPn">(</span><span class="RktSym">make-spec</span><span class="stt"> </span><a href="part_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a><span class="stt"> </span><a href="part_four.html#%28tech._db._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">Predicate</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Use this alternative definition to represent the databases from
<a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a>. <a href="part_four.html#%28counter._db._%28exercise._ex~3adb-choice-of-rep%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><span style="font-weight: bold">Integrity Checking</span> The use of databases critically relies on their
integrity. Here &ldquo;integrity&rdquo; refers to the constraints (I1) and (I2) from
the data definition. Checking database integrity is clearly a task for a
function: <a name="(idx._db._(gentag._569._db))"></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_four.html#%28tech._db._db%29" class="techoutside" data-pltdoc="x"><span class="techinside">DB</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">do all rows in </span><span class="RktSym">db</span><span class="RktCmt"> satisfy (I1) and (I2)</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">integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">school-db</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">integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">presence-db</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;</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">integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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></p><p><div class="SIntrapara">The wording of the two constraints suggests that some function has to
produce <span class="RktVal">#true</span> for every row in the content of the given
database. Expressing this idea in code calls for a use of
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> on the content of <span class="RktSym">db</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">integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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">row-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="hspace">&nbsp;</span><span class="RktSym">row-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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">Following the <a name="(idx._db._(gentag._570._db))"></a>design recipe for the use of existing abstractions, the
template introduces the auxiliary function via a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> definition.</div></p><p><div class="SIntrapara">The design of <span class="RktSym">row-integrity-check</span> starts from this: <a name="(idx._db._(gentag._571._db))"></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_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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">does </span><span class="RktSym">row</span><span class="RktCmt"> satisfy (I1) and (I2) </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">row-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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">As always, the goal of formulating a purpose statement is to understand
the problem. Here it says that the function checks <span style="font-weight: bold">two</span>
conditions. When two tasks are involved, our <a name="(idx._db._(gentag._572._db))"></a>design guidelines call
for functions and the combination of their results:
</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length-of-row-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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">check-every-cell</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Add these functions to your wish list; their names convey their purpose.</div></p><p><div class="SIntrapara">Before we design these functions, we must contemplate whether we
can compose existing primitive operations to compute the desired
value. For example, we know that <span class="RktPn">(</span><span class="RktSym">length</span><span class="stt"> </span><span class="RktSym">row</span><span class="RktPn">)</span> counts how many
cells are in <span class="RktSym">row</span>. Pushing a bit more in this direction, we
clearly want
</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._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">This condition checks that the length of <span class="RktSym">row</span> is equal to that
of <span class="RktSym">db</span>&rsquo;s schema.</div></p><p><div class="SIntrapara">Similarly, <span class="RktSym">check-every-cell</span> calls for checking that some function
produces <span class="RktVal">#true</span> for every cell in the row. Once again, it looks
like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> might be called for:
</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._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span><span class="hspace">&nbsp;</span><span class="RktSym">cell-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The purpose of <span class="RktSym">cell-integrity-check</span> is obviously to check
constraint (I2), that is,
</div><div class="SIntrapara"><blockquote><p>whether &ldquo;the <span style="font-style: italic">i</span>th <a href="part_four.html#%28tech._db._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">Cell</span></a> satisfies the <span style="font-style: italic">i</span>th
<a href="part_four.html#%28tech._db._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">Predicate</span></a> in <span class="RktSym">db</span>&rsquo;s schema.&rdquo;</p></blockquote></div><div class="SIntrapara">And now we are stuck because this purpose statement refers to the relative
position of the given cell in <span class="RktSym">row</span>. The point of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span>
is, however, to apply <span class="RktSym">cell-integrity-check</span> to every cell <span style="font-weight: bold">uniformly</span>.</div></p><p><div class="SIntrapara">When you are stuck, you must work through examples. For auxiliary or
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> functions, it&rsquo;s best to derive these examples from the ones
for the main function. The first example for <span class="RktSym">integrity-check</span>
asserts that <span class="RktSym">school-content</span> satisfies the integrity constraints.
Clearly all rows in <span class="RktSym">school-content</span> have the same length as
<span class="RktSym">school-schema</span>. The question is why a row such as
</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">"Alice"</span><span class="hspace">&nbsp;</span><span class="RktVal">35</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">satisfies the predicates in the corresponding schema:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&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">"Name"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&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._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"Age"</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&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._integer~3f%29%29" class="RktValLink" data-pltdoc="x">integer?</a></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._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"Present"</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._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The answer is that all three applications of the three predicates to the
respective cells yields true:
</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/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"Alice"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._integer~3f%29%29" class="RktValLink" data-pltdoc="x">integer?</a></span><span class="hspace">&nbsp;</span><span class="RktVal">35</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr></table></blockquote></div><div class="SIntrapara">From here, it is just a short step to see that the function must process
these two lists&#8212;<wbr></wbr><span class="RktSym">db</span>&rsquo;s schema and the given row&#8212;<wbr></wbr>in parallel.</div></p><p><a name="(counter._db._(exercise._ex~3aandmap2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;404. Design the function <span class="RktSym">andmap2</span>. It consumes a
function <span class="RktSym">f</span> from two values to <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> and two equally long
lists. Its result is also a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>. Specifically, it applies
<span class="RktSym">f</span> to pairs of corresponding values from the two lists, and if
<span class="RktSym">f</span> always produces <span class="RktVal">#true</span>, <span class="RktSym">andmap2</span> produces
<span class="RktVal">#true</span>, too. Otherwise, <span class="RktSym">andmap2</span> produces
<span class="RktVal">#false</span>. In short, <span class="RktSym">andmap2</span> is like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> but for
two lists. <a href="part_four.html#%28counter._db._%28exercise._ex~3aandmap2%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Stop! Solve <a href="part_four.html#%28counter._db._%28exercise._ex~3aandmap2%29%29" data-pltdoc="x">exercise&nbsp;404</a> before reading on.</p><p><div class="SIntrapara">If we had <span class="RktSym">andmap2</span> in ISL+, checking the second condition on
<span class="RktSym">row</span> would be straightforward:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">andmap2</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">s</span><span class="hspace">&nbsp;</span><span class="RktSym">c</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#%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="RktSym">s</span><span class="RktPn">)</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;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The given function consumes a <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> <span class="RktSym">s</span> from <span class="RktSym">db</span>&rsquo;s
schema, extracts the predicate in the second position, and applies it to
the given <a href="part_four.html#%28tech._db._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">Cell</span></a> <span class="RktSym">c</span>. Whatever the predicate returns is the
result of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span> function.</div></p><p>Stop again! Explain <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._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">c</span><span class="RktPn">]</span>.</p><p><div class="SIntrapara">As it turns out, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</a></span> in ISL+ is already like
<span class="RktSym">andmap2</span>: <a name="(idx._db._(gentag._573._db))"></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">integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does </span><span class="RktSym">row</span><span class="RktCmt"> satisfy (I1) and (I2) </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">row-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</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">length</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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._andmap%29%29" class="RktValLink" data-pltdoc="x">andmap</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.
<span class="RktSym">integrity-check</span> suffers from several problems, some visible, some
invisible. Clearly, the function extracts <span class="RktSym">db</span>&rsquo;s schema twice. With
the existing <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 it is possible to introduce a
definition and avoid this duplication:</p><p><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">integrity-check.v2</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">schema</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does </span><span class="RktSym">row</span><span class="RktCmt"> satisfy (I1) and (I2) </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">row-integrity-check</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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._and%29%29" class="RktStxLink" data-pltdoc="x">and</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">length</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktSym">schema</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="h
expression may shorten the time needed to run the integrity check. Like
the definition of <span class="RktSym">inf</span> in <a href="part_three.html#%28counter._%28figure._fig~3alocal-performance%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">100</span></a>, the
original version of <span class="RktSym">integrity-check</span> extracts the schema from
<span class="RktSym">db</span> for every single row, even though it obviously stays
the same.</div></p><p><div class="SIntrapara"><a name="(idx._db._(gentag._574._db))"></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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">integrity-check.v3</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">schema</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">width</span><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktSym">schema</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does </span><span class="RktSym">row</span><span class="RktCmt"> satisfy (I1) and (I2) </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">row-integrity-check</span><span class="hspace">&nbsp;</span><span cl
In a similar vein, the <span class="RktSym">row-integrity-check</span> function determines the
length of <span class="RktSym">db</span>&rsquo;s schema every single time it is called. The result
is always the same. Hence, if we are interested in improving the
performance of this function, we can use a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> definition to
name the <span class="RktSym">width</span> of the database content once and for
all. <a href="part_four.html#%28counter._db._%28figure._fig~3ahoisted%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">139</span></a> displays the result of hoisting
<span class="RktPn">(</span><span class="RktSym">length</span><span class="stt"> </span><span class="RktSym">schema</span><span class="RktPn">)</span> out of the <span class="RktSym">row-integrity-check</span>. For
readability, this final definition also names the <span class="RktSym">content</span> field
of <span class="RktSym">db</span>. <span style="font-weight: bold">End</span></p><p><span style="font-weight: bold">Projections and Selections</span> Programs need to extract data from
databases. One kind of extraction is to <span style="font-style: italic">select</span> content, which is
explained in <a href="part_two.html#%28part._itunes-data._sec~3aitunes%29" data-pltdoc="x">Real-World Data: iTunes</a>. The other
kind of extraction produces a reduced database; it is dubbed
<span style="font-style: italic">projection</span>. More specifically, a projection constructs a database
by retaining only certain columns from a given database.</p><p><div class="SIntrapara">The description of a projection suggests the following: <a name="(idx._db._(gentag._575._db))"></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_four.html#%28tech._db._db%29" class="techoutside" data-pltdoc="x"><span class="techinside">DB</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_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a><span class="RktCmt">] -&gt; </span><a href="part_four.html#%28tech._db._db%29" class="techoutside" data-pltdoc="x"><span class="techinside">DB</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retains a column from </span><span class="RktSym">db</span><span class="RktCmt"> if its label is in </span><span class="RktSym">labels</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">project</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-db</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></table></blockquote></div><div class="SIntrapara">Given the complexity of a projection, it is best to work through an
example first. Say we wish to eliminate the age column from
the database on the left in <a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a>. Here is what this
transformation looks like in terms of tables:
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="center" style="border-bottom: 1px solid black;"><p>the original database</p></td><td align="center" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center" style="border-bottom: 1px solid black;"><p>... eliminating the &ldquo;Age&rdquo; column</p></td></tr><tr><td align="center"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Age</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Present</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr></table></td><td align="center"><p><span class="hspace">&nbsp;&nbsp;</span></p></td><td align="center"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Present</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left
</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">projected-content</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">"Alice"</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Bob"</span><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVal">#false</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Carol"</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Dave"</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">#false</span><span class="RktVal">)</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="RktSym">projected-schema</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">"Name"</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><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~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="RktVal">)</span><span class="hspace">&nbsp;</span><span class="RktVal">(</span><span class="RktVal">"Present"</span><span class="hspace">&nbsp;</span><span class="RktRdr">,</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._boolean~3f%29%29" class="RktValLink" data-pltdoc="x">boolean?</a></span><span class="RktVal">)</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="RktSym">projected-db</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-db</span><span class="hspace">&nbsp;</span><span class="RktSym">projected-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">projected-content</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"> Stop! Read this test carefully. What</span><span class="RktCmt">'</span><span class="RktCmt">s wrong?</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">chec
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">project</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</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="RktSym">schema</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does this spec belong to the new schema</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">keep?</span><span class="hspace">&nbsp;</span><span class="RktSym">c</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;</span><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a><span class="RktCmt"> -&gt; </span
</div><div class="SIntrapara"><blockquote class="SCentered"><p><span class="stt">first argument of equality cannot be a function</span></p></blockquote></div><div class="SIntrapara">before DrRacket can even figure out whether the test succeeds. Recall from
<a href="part_three.html#%28part._sec~3afunctions-as-values%29" data-pltdoc="x">Functions Are Values</a> that
functions are infinitely large objects and it is impossible to ensure that
two functions always produce the same result when applied to the same
arguments. We therefore weaken the test case:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">project</span><span class="hspace">&nbsp;</span><span class="RktSym">school-db</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"Name"</span><span class="hspace">&nbsp;</span><span class="RktVal">"Present"</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="RktSym">projected-content</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>For the template, we again reuse existing abstractions; see
<a href="part_four.html#%28counter._db._%28figure._fig~3aproject-template%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">140</span></a>. 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 defines
two functions: one for use 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._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> for narrowing down the
schema of the given database and the other for use 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._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> for
thinning out the content. In addition, the function again extracts and
names the schema and the content from the given database.</p><p>Before we turn to the wish list, let&rsquo;s step back and study
the decision to go with two reuses of existing abstraction. The signature
tells us that the function consumes a structure and produces an element of
<a href="part_four.html#%28tech._db._db%29" class="techoutside" data-pltdoc="x"><span class="techinside">DB</span></a>, so</p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace">&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">schema</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">make-db</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">schema</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;</span><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">content</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></table></blockquote></div><div class="SIntrapara">is clearly called for. It is also straightforward to see that the new
schema is created from the old schema and the new content from the old
content. Furthermore, the purpose statement of <span class="RktSym">project</span> calls for
the retention of only those labels that are mentioned in the second
argument. Hence, 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._filter%29%29" class="RktValLink" data-pltdoc="x">filter</a></span> function correctly narrows down the
given <span class="RktSym">schema</span>. In contrast, the rows per se stay except that each
of them loses some cells. Thus, <span class="RktSym"><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> is the proper way of
processing <span class="RktSym">content</span>.</div></p><p><div class="SIntrapara">Now we can turn to the design of the two auxiliary functions. The
design of <span class="RktSym">keep?</span> is straightforward. Here is the complete
definition: <a name="(idx._db._(gentag._577._db))"></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_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</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">does this spec belong to the new schema</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">keep?</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#%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="RktPn">(</span><span class="RktSym"><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">c</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The function is applied to a <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a>, which combines a <a href="part_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a>
and a <a href="part_four.html#%28tech._db._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">Predicate</span></a> in a list. If the former belongs to <span class="RktSym">labels</span>,
the given <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> is kept.</div></p><p><div class="SIntrapara">For the design of <span class="RktSym">row-project</span>, the goal is to keep those
<a href="part_four.html#%28tech._db._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">Cell</span></a>s in each <a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a> of <span class="RktSym">content</span> whose name is a member
of the given <span class="RktSym">labels</span>. Let&rsquo;s work through the above example.
The four rows are:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"Alice"</span><span class="hspace">&nbsp;</span><span class="RktVal">35</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#%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">"Bob"</span><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVal">25</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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">"Carol"</span><span class="hspace">&nbsp;</span><span class="RktVal">30</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#%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">"Dave"</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktVal">32</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Each of these rows is as long as <span class="RktSym">school-schema</span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%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">"Name"</span><span class="hspace">&nbsp;</span><span class="RktVal">"Age"</span><span class="hspace">&nbsp;</span><span class="RktVal">"Present"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The names in the schema determine the names of the cells in the given
rows. Hence, <span class="RktSym">row-project</span> must keep the first and third cell of
each row because it is their names that are in the given <span class="RktSym">labels</span>.</div></p><p><div class="SIntrapara">Since <a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a> is defined recursively, this matching process between the
content of the <a href="part_four.html#%28tech._db._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">Cell</span></a>s and their names calls for a recursive helper
function that <span class="RktSym">row-project</span> can apply to the content and the labels
of the cells. Let&rsquo;s specify it as a wish: <a name="(idx._db._(gentag._578._db))"></a> <a name="(idx._db._(gentag._579._db))"></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_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</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_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a><span class="RktCmt">] -&gt; </span><a href="part_four.html#%28tech._db._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">retains those cells whose corresponding element </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">in </span><span class="RktSym">names</span><span class="RktCmt"> is also in </span><span class="RktSym">labels</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">row-filter</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="hspace">&nbsp;</span><span class="RktSym">names</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></table></blockquote></div><div class="SIntrapara">Using this wish, <span class="RktSym">row-project</span> is a one-liner:
</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">row-project</span><span class="hspace">&nbsp;</span><span class="RktSym">row</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">row-filter</span><span class="hspace">&nbsp;</span><span class="RktSym">row</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._map%29%29" class="RktValLink" data-pltdoc="x">map</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._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">schema</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span> expression extracts the names of the cells,
and those names are handed to <span class="RktSym">row-filter</span> to extract the matching
cells.</div></p><p><a name="(counter._db._(exercise._ex~3arow-filter))"></a><span style="font-weight: bold">Exercise</span>&nbsp;405. Design the function <span class="RktSym">row-filter</span>.
Construct examples for <span class="RktSym">row-filter</span> from the examples for
<span class="RktSym">project</span>.</p><p><span style="font-weight: bold">Assumption</span> The given database passes an integrity check, meaning
each row is as long as the schema and thus its list of names. <a href="part_four.html#%28counter._db._%28exercise._ex~3arow-filter%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a href="part_four.html#%28counter._db._%28figure._fig~3adb-project%29%29" data-pltdoc="x">Figure&nbsp;<span class="FigureRef">141</span></a> puts all the pieces together. The function
<span class="RktSym">project</span> has the suffix <span class="stt">.v1</span> because it calls for some
improvement. The following exercises ask you to implement some of those.</p><p><div class="SIntrapara"><a name="(idx._db._(gentag._580._db))"></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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">project.v1</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</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="RktSym">schema</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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><a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does this column belong to the new schema</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">keep?</span><span class="hspace">&nbsp;</span><span class="RktSym">c</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._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</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-lamb
recomputes the labels for every row of the database&rsquo;s content. Does the
result differ from function call to function call? If not, hoist the expression. <a href="part_four.html#%28counter._db._%28exercise._ex~3arow-project-hoist%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._db._(exercise._ex~3arow-filter/fold))"></a><span style="font-weight: bold">Exercise</span>&nbsp;407. Redesign <span class="RktSym">row-filter</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._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span>. Once you have done so, you may merge <span class="RktSym">row-project</span>
and <span class="RktSym">row-filter</span> into a single function. <span style="font-weight: bold">Hint</span> The
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> function in ISL+ may consume two lists and process them
in parallel. <a href="part_four.html#%28counter._db._%28exercise._ex~3arow-filter%2Ffold%29%29" class="ex-end" data-pltdoc="x"></a></p><p>The final observation is that <span class="RktSym">row-project</span> checks the membership of
a label in <span class="RktSym">labels</span> for every single cell. For the cells of the
same column in different rows, the result is going to be the same. Hence
it also makes sense to hoist this computation out of the function.</p><p><div class="SIntrapara">This form of hoisting is somewhat more difficult than plain expression
hoisting. We basically wish to pre-compute the result of
</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._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">label</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">for all rows and pass the results into the function instead of the list of
labels. That is, we replace the list of labels with a list of <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s
that indicate whether the cell in the corresponding position is to be
kept. Fortunately, computing those <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s is just another application of
<span class="RktSym">keep?</span> on the schema:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._map%29%29" class="RktValLink" data-pltdoc="x">map</a></span><span class="hspace">&nbsp;</span><span class="RktSym">keep?</span><span class="hspace">&nbsp;</span><span class="RktSym">schema</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Instead of keeping some <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a>s from the given <span class="RktSym">schema</span> and
throwing away the others, this expression just collects the decisions.</div></p><p><div class="SIntrapara"><a name="(idx._db._(gentag._581._db))"></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%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">project</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="hspace">&nbsp;</span><span class="RktSym">labels</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="RktSym">schema</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-schema</span><span class="hspace">&nbsp;</span><span class="RktSym">db</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="RktSym">content</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">db-content</span><span class="hspace">&nbsp;</span><span class="RktSym">db</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;</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><a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</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="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">does this column belong to the new schema</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">keep?</span><span class="hspace">&nbsp;</span><span class="RktSym">c</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._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</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.
integrates the solutions for the preceding exercises. It also 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 extract and name <span class="RktSym">schema</span> and <span class="RktSym">content</span>,
plus <span class="RktSym">keep?</span> for checking whether the label in some <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> is
worth keeping. The remaining two definitions introduce <span class="RktSym">mask</span>, which
stands for the list of <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s discussed above, and the revised version of
<span class="RktSym">row-project</span>. The latter 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._foldr%29%29" class="RktValLink" data-pltdoc="x">foldr</a></span> to process the given
<span class="RktSym">row</span> and <span class="RktSym">mask</span> in parallel.</p><p>Compare this revised definition of <span class="RktSym">project</span> with <span class="RktSym">project.v1</span>
in <a href="part_four.html#%28counter._db._%28figure._fig~3adb-project%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">141</span></a>. The final definition is both simpler and
faster than the original version. Systematic design combined with careful
revisions pays off; <a name="(idx._db._(gentag._582._db))"></a>test suites ensure that revisions don&rsquo;t mess up the
functionality of the program.</p><p><a name="(counter._db._(exercise._ex~3adb-select))"></a><span style="font-weight: bold">Exercise</span>&nbsp;408. Design the function <span class="RktSym">select</span>. It consumes a
database, a list of labels, and a predicate on rows. The result is a list of
rows that satisfy the given predicate, projected down to the given set of
labels. <a href="part_four.html#%28counter._db._%28exercise._ex~3adb-select%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._db._(exercise._ex~3adb-reorder))"></a><span style="font-weight: bold">Exercise</span>&nbsp;409. Design <span class="RktSym">reorder</span>. The function consumes a
database <span class="RktSym">db</span> and list <span class="RktSym">lol</span> of <a href="part_four.html#%28tech._db._label%29" class="techoutside" data-pltdoc="x"><span class="techinside">Label</span></a>s. It produces a
database like <span class="RktSym">db</span> but with its columns reordered according to
<span class="RktSym">lol</span>. <span style="font-weight: bold">Hint</span> 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._list-ref%29%29" class="RktValLink" data-pltdoc="x">list-ref</a></span>.</p><p>At first assume that <span class="RktSym">lol</span> consists exactly of the labels of
<span class="RktSym">db</span>&rsquo;s columns. Once you have completed the design, study what has
to be changed if <span class="RktSym">lol</span> contains fewer labels than there are columns
and strings that are not labels of a column in <span class="RktSym">db</span>. <a href="part_four.html#%28counter._db._%28exercise._ex~3adb-reorder%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._db._(exercise._ex~3adb-union))"></a><span style="font-weight: bold">Exercise</span>&nbsp;410. Design the function <span class="RktSym">db-union</span>, which
consumes two databases with the exact same schema and produces a new
database with this schema and the joint content of both. The function must
eliminate rows with the exact same content.</p><p>Assume that the schemas agree on the predicates for each column. <a href="part_four.html#%28counter._db._%28exercise._ex~3adb-union%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._db._(exercise._ex~3adb-join))"></a><span style="font-weight: bold">Exercise</span>&nbsp;411. Design <span class="RktSym">join</span>, a function that consumes two
databases: <span class="RktSym">db-1</span> and <span class="RktSym">db-2</span>. The schema of <span class="RktSym">db-2</span>
starts with the exact same <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> that the schema of <span class="RktSym">db-1</span>
ends in. The function creates a database from <span class="RktSym">db-1</span> by
replacing the last cell in each row with the <span style="font-style: italic">translation</span> of the cell
in <span class="RktSym">db-2</span>.</p><p><div class="SIntrapara">Here is an example. Take the databases in <a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a>. The
two satisfy the assumption of these exercises, that is, the last
<a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> in the schema of the first is equal to the first <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a>
of the second. Hence it is possible to join them:
</div><div class="SIntrapara"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Age</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Description</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"presence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"absence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"presence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"absence"</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Its translation maps <span class="RktVal">#true</span> to <span class="RktVal">"presence"</span> and
<span class="RktVal">#false</span> to <span class="RktVal">"absence"</span>.</div></p><p><span style="font-weight: bold">Hints</span> (1) In general, the second database may &ldquo;translate&rdquo; a cell to
a row of values, not just one value. Modify the example by adding additional terms
to the row for <span class="RktVal">"presence"</span> and <span class="RktVal">"absence"</span>.</p><p><div class="SIntrapara">(2) It may also &ldquo;translate&rdquo; a cell to several rows, in which case the
process adds several rows to the new database. Here is a second example, a
slightly different pair of databases from those in
<a href="part_four.html#%28counter._db._%28figure._fig~3adb-tables%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">137</span></a>:
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Age</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Present</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#true</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">#false</span></p></td></tr></table></td><td><p><span class="hspace">&nbsp;</span></p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td style="border-right: 1px solid black;"><p><span class="hspace">&nbsp;</span></p></td><td><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Present</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Description</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">#true</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"presence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">#true<
eight rows:
</div><div class="SIntrapara"><blockquote class="SCentered"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="left"><p>Name</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Age</p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p>Description</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._integer%29" class="techoutside" data-pltdoc="x"><span class="techinside">Integer</span></a></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"presence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Alice"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">35</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"here"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"absence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Bob"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">25</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"there"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"presence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Carol"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">30</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"here"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">"absence"</span></p></td></tr><tr><td align="left"><p><span class="RktVal">"Dave"</span></p></td><td align="left"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td align="left"><p><span class="RktVal">32</span></p></td><td align="left"><p><span class=
assume that a &ldquo;translation&rdquo; finds only one row per cell. For the second
one, drop the assumption.</p><p><span style="font-weight: bold">Note on Assumptions</span> This exercise and the entire section mostly rely
on informally stated assumptions about the given databases. Here, the
design of <span class="RktSym">join</span> assumes that &ldquo;the schema of <span class="RktSym">db-2</span> starts
with the exact same <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> that the schema of <span class="RktSym">db-1</span> ends
in.&rdquo; In reality, database functions must be checked functions in the
spirit of <a href="part_one.html#%28part._sec~3ainput-errors%29" data-pltdoc="x">Input Errors</a>. Designing <span class="RktSym">checked-join</span> would
be impossible for you, however. A comparison of the last <a href="part_four.html#%28tech._db._spec%29" class="techoutside" data-pltdoc="x"><span class="techinside">Spec</span></a> in
the schema of <span class="RktSym">db-1</span> with the first one in <span class="RktSym">db-2</span> calls for
a comparison of functions. For practical solutions, see a text on databases. <a href="part_four.html#%28counter._db._%28exercise._ex~3adb-join%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>24<tt>&nbsp;</tt><a name="(part._ch~3asummary4)"></a>Summary</h3><p><div class="SIntrapara">This fourth part of the book is about the design of functions that process
data whose description requires many intertwined definitions. These forms
of data show up everywhere in the real world, from your computer&rsquo;s local
file system to the world wide web and geometric shapes used in animated
movies. After working through this part of the book carefully, you know
that the <a name="(idx._(gentag._583))"></a>design recipe scales to these forms of data, too:
</div><div class="SIntrapara"><ol><li><p>When the description of program data calls for several mutually
referential data definitions, the design recipe calls for the simultaneous
development of <a name="(idx._(gentag._584))"></a>templates, one per data definition. If a data definition
<span class="stt">A</span> refers to a data definition <span class="stt">B</span>, then the
template <span class="RktSym">function-for-A</span> refers to <span class="RktSym">function-for-B</span> in the
exact same place and manner. Otherwise the design recipes work as before,
function for function.</p></li><li><p>When a function has to process two types of complex data, you need to
distinguish three cases. First, the function may deal with one of the
arguments as if it were atomic. Second, the two arguments are expected to
have the exact same structure, and the function traverses them in a
completely parallel manner. Third, the function may have to deal with all
possible combinations separately. In this case, you make a two-dimensional
table that along one dimension enumerates all kinds of data from one data
definition and along the other one deals with the second kind of
data. Finally you use the table&rsquo;s cells to formulate conditions and
answers for the various cases.</p><p>This part of the book deals with functions on two complex arguments. If
you ever encounter one of those rare cases where a function receives three
complex pieces of data, you know you need (to imagine) a three-dimensional
table.</p></li></ol></div><div class="SIntrapara">You have now seen all forms of <a name="(idx._(gentag._585))"></a>structural data that you are likely to
encounter over the course of your career, though the details will
differ. If you are ever stuck, remember the <a name="(idx._(gentag._586))"></a>design recipe; it will get you
started.</div></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="i3-4.html" title="backward to &quot;Intermezzo 3: Scope and Abstraction&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="i4-5.html" title="forward to &quot;Intermezzo 4: The Nature of Numbers&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>