2768 lines
No EOL
1.3 MiB
2768 lines
No EOL
1.3 MiB
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>II Arbitrarily Large 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="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="figure.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-racket.css" title="default"/><script type="text/javascript" src="scribble-common.js"></script><script type="text/javascript" src="figure.js"></script><script type="text/javascript" src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">▼</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">How to Design Programs, Second Edition</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right"></td><td><a href="part_preface.html" class="tocviewlink" data-pltdoc="x">Preface</a></td></tr><tr><td align="right"></td><td><a href="part_prologue.html" class="tocviewlink" data-pltdoc="x">Prologue:<span class="mywbr"> </span> How to Program</a></td></tr><tr><td align="right">I </td><td><a href="part_one.html" class="tocviewlink" data-pltdoc="x">Fixed-<wbr></wbr>Size Data</a></td></tr><tr><td align="right"></td><td><a href="i1-2.html" class="tocviewlink" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a></td></tr><tr><td align="right">II </td><td><a href="part_two.html" class="tocviewselflink" data-pltdoc="x">Arbitrarily Large Data</a></td></tr><tr><td align="right"></td><td><a href="i2-3.html" class="tocviewlink" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a></td></tr><tr><td align="right">III </td><td><a href="part_three.html" class="tocviewlink" data-pltdoc="x">Abstraction</a></td></tr><tr><td align="right"></td><td><a href="i3-4.html" class="tocviewlink" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a></td></tr><tr><td align="right">IV </td><td><a href="part_four.html" class="tocviewlink" data-pltdoc="x">Intertwined Data</a></td></tr><tr><td align="right"></td><td><a href="i4-5.html" class="tocviewlink" data-pltdoc="x">Intermezzo 4: The Nature of Numbers</a></td></tr><tr><td align="right">V </td><td><a href="part_five.html" class="tocviewlink" data-pltdoc="x">Generative Recursion</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html" class="tocviewlink" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a></td></tr><tr><td align="right">VI </td><td><a href="part_six.html" class="tocviewlink" data-pltdoc="x">Accumulators</a></td></tr><tr><td align="right"></td><td><a href="part_epilogue.html" class="tocviewlink" data-pltdoc="x">Epilogue:<span class="mywbr"> </span> Moving On</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_1");">►</a></td><td>II </td><td><a href="part_two.html" class="tocviewselflink" data-pltdoc="x">Arbitrarily Large Data</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">8 </td><td><a href="part_two.html#%28part._ch~3alists1%29" class="tocviewlink" data-pltdoc="x">Lists</a></td></tr><tr><td align="right">9 </td><td><a href="part_two.html#%28part._ch~3adesign-lists%29" class="tocviewlink" data-pltdoc="x">Designing with Self-<wbr></wbr>Referential Data Definitions</a></td></tr><tr><td align="right">10 </td><td><a href="part_two.html#%28part._ch~3alists2%29" class="tocviewlink" data-pltdoc="x">More on Lists</a></td></tr><tr><td align="right">11 </td><td><a href="part_two.html#%28part._ch~3alist-sort%29" class="tocviewlink" data-pltdoc="x">Design by Composition</a></td></tr><tr><td align="right">12 </td><td><a href="part_two.html#%28part._ch~3aproj-lists%29" class="tocviewlink" data-pltdoc="x">Projects:<span class="mywbr"> </span> Lists</a></td></tr><tr><td align="right">13 </td><td><a href="part_two.html#%28part._ch~3asummary2%29" class="tocviewlink" data-pltdoc="x">Summary</a></td></tr></table></div></div></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="version">8.6.0.2</span></div><div class="navsettop"><span class="navleft"><div class="nosearchform"></div> <span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="i1-2.html" title="backward to "Intermezzo 1: Beginning Student Language"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "How to Design Programs, Second Edition"" data-pltdoc="x">up</a> <a href="i2-3.html" title="forward to "Intermezzo 2: Quote, Unquote"" data-pltdoc="x">next →</a></span> </div><h3>II<tt> </tt><a name="(part._part~3atwo)"></a>Arbitrarily Large Data</h3><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3alists1%29" class="toclink" data-pltdoc="x">8<span class="hspace"> </span>Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alists-records%29" class="toclink" data-pltdoc="x">8.1<span class="hspace"> </span>Creating Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alists-cons%29" class="toclink" data-pltdoc="x">8.2<span class="hspace"> </span>What Is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, What Is <span class="RktSym"><span class="RktValLink">cons</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alists-programming%29" class="toclink" data-pltdoc="x">8.3<span class="hspace"> </span>Programming with Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3aeval-list%29" class="toclink" data-pltdoc="x">8.4<span class="hspace"> </span>Computing with Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3adesign-lists%29" class="toclink" data-pltdoc="x">9<span class="hspace"> </span>Designing with Self-Referential Data Definitions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3afinger-lists%29" class="toclink" data-pltdoc="x">9.1<span class="hspace"> </span>Finger Exercises: Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alists~3ane%29" class="toclink" data-pltdoc="x">9.2<span class="hspace"> </span>Non-empty Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3anats%29" class="toclink" data-pltdoc="x">9.3<span class="hspace"> </span>Natural Numbers</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._rd._sec~3ard%29" class="toclink" data-pltdoc="x">9.4<span class="hspace"> </span>Russian Dolls</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alist-world%29" class="toclink" data-pltdoc="x">9.5<span class="hspace"> </span>Lists and World</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alist-set%29" class="toclink" data-pltdoc="x">9.6<span class="hspace"> </span>A Note on Lists and Sets</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3alists2%29" class="toclink" data-pltdoc="x">10<span class="hspace"> </span>More on Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alist-produce%29" class="toclink" data-pltdoc="x">10.1<span class="hspace"> </span>Functions that Produce Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3asil%29" class="toclink" data-pltdoc="x">10.2<span class="hspace"> </span>Structures in Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3alis-lis%29" class="toclink" data-pltdoc="x">10.3<span class="hspace"> </span>Lists in Lists, Files</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._list-edit2._sec~3aedit2%29" class="toclink" data-pltdoc="x">10.4<span class="hspace"> </span>A Graphical Editor, Revisited</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3alist-sort%29" class="toclink" data-pltdoc="x">11<span class="hspace"> </span>Design by Composition</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3aabbrev%29" class="toclink" data-pltdoc="x">11.1<span class="hspace"> </span>The <span class="RktSym"><span class="RktValLink">list</span></span> Function</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3acompounding2%29" class="toclink" data-pltdoc="x">11.2<span class="hspace"> </span>Composing Functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3asort.I%29" class="toclink" data-pltdoc="x">11.3<span class="hspace"> </span>Auxiliary Functions that Recur</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3agen-funcs%29" class="toclink" data-pltdoc="x">11.4<span class="hspace"> </span>Auxiliary Functions that Generalize</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3aproj-lists%29" class="toclink" data-pltdoc="x">12<span class="hspace"> </span>Projects: Lists</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3adict%29" class="toclink" data-pltdoc="x">12.1<span class="hspace"> </span>Real-World Data: Dictionaries</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._itunes-data._sec~3aitunes%29" class="toclink" data-pltdoc="x">12.2<span class="hspace"> </span>Real-World Data: iTunes</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3apermute-composition%29" class="toclink" data-pltdoc="x">12.3<span class="hspace"> </span>Word Games, Composition Illustrated</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3apermute%29" class="toclink" data-pltdoc="x">12.4<span class="hspace"> </span>Word Games, the Heart of the Problem</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3aworms%29" class="toclink" data-pltdoc="x">12.5<span class="hspace"> </span>Feeding Worms</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3atetris%29" class="toclink" data-pltdoc="x">12.6<span class="hspace"> </span>Simple Tetris</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3aspace-war%29" class="toclink" data-pltdoc="x">12.7<span class="hspace"> </span>Full Space War</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._sec~3asec-fsm-list%29" class="toclink" data-pltdoc="x">12.8<span class="hspace"> </span>Finite State Machines</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="part_two.html#%28part._ch~3asummary2%29" class="toclink" data-pltdoc="x">13<span class="hspace"> </span>Summary</a></p></td></tr></table><p>Every data definition in <a href="part_one.html" data-pltdoc="x">Fixed-Size Data</a> describes data of a fixed
|
|
size. To us, Boolean values, numbers, strings, and images are atomic;
|
|
computer scientists say they have a size of one unit. With a structure,
|
|
you compose a fixed number of pieces of data. Even if you use the language
|
|
of data definitions to create deeply nested structures, you always know the
|
|
exact number of atomic pieces of data in any specific instance. Many
|
|
programming problems, however, deal with an undetermined number of pieces
|
|
of information that must be processed as one piece of data. For example,
|
|
one program may have to compute the average of a bunch of numbers and
|
|
another may have to keep track of an arbitrary number of objects in an
|
|
interactive game. Regardless, it is impossible with your knowledge to
|
|
formulate a data definition that can represent this kind of information as
|
|
data.</p><p>This part revises the language of data definitions so that it becomes
|
|
possible to describe data of (finite but) arbitrary size. For a concrete
|
|
illustration, the first half of this part deals with lists, a form of data
|
|
that appears in most modern programming languages. In parallel with the
|
|
extended language of data definitions, this part also revises the design
|
|
recipe to cope with such data definitions. The latter chapters demonstrate
|
|
how these data definitions and the revised design recipe work in a variety
|
|
of contexts.</p><h3>8<tt> </tt><a name="(part._ch~3alists1)"></a>Lists</h3><p>You have probably not encountered self-referential definitions before. Your
|
|
English teachers certainly stay away from these, and many mathematics
|
|
courses are vague when it comes to such definitions. Programmers cannot
|
|
afford to be vague. Their work requires precision. While a definition may
|
|
in general contain several references to itself, this chapter presents
|
|
useful examples that need just one, starting with the one for lists.</p><p>The introduction of lists also spices up the kind of applications we can
|
|
study. While this chapter carefully builds up your intuition with
|
|
examples, it also motivates the revision of the design recipe in
|
|
the next chapter, which explains how to systematically create functions
|
|
that deal with self-referential data definitions.</p><h4>8.1<tt> </tt><a name="(part._sec~3alists-records)"></a>Creating Lists</h4><p>All of us make lists all the time. Before we go grocery shopping, we write
|
|
down a list of items we wish to purchase. Some people write down a to-do
|
|
list every morning. During December, many children prepare Christmas wish
|
|
lists. To plan a party, we make a list of invitees. Arranging
|
|
information in the form of lists is an ubiquitous part of our life.</p><p>Given that information comes in the shape of lists, we must clearly learn
|
|
how to represent such lists as BSL data. Indeed, because lists are so
|
|
important, BSL comes with built-in support for creating and manipulating
|
|
lists, similar to the support for Cartesian points (<span class="RktSym">posn</span>). In contrast to points,
|
|
the data definition for lists is always left to you. But first things
|
|
first. We start with the creation of lists.</p><p><div class="SIntrapara">When we form a list, we always start out with the empty list. In BSL, we
|
|
represent the <span style="font-style: italic">empty</span> list with
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">which is pronounced “empty,” short for “empty list.” Like
|
|
<span class="RktVal">#true</span> or <span class="RktVal">5</span>, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is just a constant. When we add
|
|
something to a list, we construct another list; in BSL, the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> operation serves this purpose. For example,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">constructs a list from the <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> list and the string
|
|
<span class="RktVal">"Mercury"</span>. <a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">Figure <span class="FigureRef">44</span></a> presents this list in the
|
|
same pictorial manner we used for structures. The box for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>
|
|
has two fields: <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>. In this specific example
|
|
the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> field contains <span class="RktVal">"Mercury"</span> and the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>
|
|
field contains <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><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">list</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">diagram</span></p></td></tr><tr><td align="left" valign="bottom"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="bottom"><p><span class="hspace"> </span></p></td><td align="left" valign="bottom"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_89.png" alt="image" width="92.728515625" height="53.861328125"/></p></td></tr><tr><td align="left" valign="bottom"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Venus"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="bottom"><p><span class="hspace"> </span></p></td><td align="left" valign="bottom"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_90.png" alt="image" width="150.6513671875" height="85.64453125"/></p></td></tr><tr><td align="left" valign="bottom"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Earth"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Venus"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="bottom"><p><span class="hspace"> </span></p></td><td align="left" valign="bottom"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_91.png" alt="image" width="206.0244140625" height="117.427734375"/></p></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3abuild-a-list))" x-target-lift="Figure"></a>Figure 44: </span>Building a list</span></p></blockquote><p><div class="SIntrapara">Once we have a list with one item in it, we can construct lists
|
|
with two items by using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> again. Here is one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Venus"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">And here is another:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Earth"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The middle row of <a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">figure <span class="FigureRef">44</span></a> shows how you can imagine
|
|
lists that contain two items. It is also a box of two fields, but this
|
|
time the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field contains a box. Indeed, it contains the box
|
|
from the top row of the same figure.</div></p><p><div class="SIntrapara">Finally, we construct a list with three items:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Earth"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Venus"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The last row of <a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">figure <span class="FigureRef">44</span></a> illustrates the list with three
|
|
items. Its <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field contains a box that contains a box
|
|
again. So, as we create lists we put boxes into boxes into boxes,
|
|
and so on. While this may appear strange at first glance, it is just like a set
|
|
of Chinese gift boxes or a set of nested drinking cups, which we sometimes
|
|
get for birthdays. The only difference is that BSL programs can nest
|
|
lists much deeper than any artist could nest physical boxes.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Earth"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Venus"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Mercury"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_92.png" alt="image" width="336.0244140625" height="103.861328125"/></p></td></tr><tr><td><p></p></td><td><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_93.png" alt="image" width="336.0244140625" height="103.861328125"/></p></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3alist-box))" x-target-lift="Figure"></a>Figure 45: </span>Drawing a list</span></p></blockquote><p>Because even good artists would have problems with drawing deeply nested
|
|
structures, computer scientists resort to box-and-arrow diagrams
|
|
instead. <a href="part_two.html#%28counter._%28figure._fig~3alist-box%29%29" data-pltdoc="x">Figure <span class="FigureRef">45</span></a> illustrates how to rearrange the last row
|
|
of <a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">figure <span class="FigureRef">44</span></a>. Each <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> structure becomes a
|
|
separate box. If the rest field is too complex to be drawn inside of the
|
|
box, we draw a bullet instead and a line with an arrow to the box that it
|
|
contains. Depending on how the boxes are arranged, you get two kinds of
|
|
diagrams. The first, displayed in the top row of <a href="part_two.html#%28counter._%28figure._fig~3alist-box%29%29" data-pltdoc="x">figure <span class="FigureRef">45</span></a>,
|
|
lists the boxes in the order in which they are created. The second,
|
|
displayed in the bottom row, lists the boxes in the order in which they
|
|
are <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed together. Hence the second diagram immediately tells
|
|
you what <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> would have produced when applied to the list, no matter
|
|
how long the list is. For this reason, programmers prefer the second
|
|
arrangement.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist1))"></a><span style="font-weight: bold">Exercise</span> 129. Create BSL lists that represent
|
|
</div><div class="SIntrapara"><ol><li><p>a list of celestial bodies, say, at least all the planets in our solar system;</p></li><li><p>a list of items for a meal, for example, steak, french fries, beans, bread, water,
|
|
Brie cheese, and ice cream; and</p></li><li><p>a list of colors.</p></li></ol></div><div class="SIntrapara">Sketch some box representations of these lists, similar to those in
|
|
<a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">figures <span class="FigureRef">44</span></a> and <a href="part_two.html#%28counter._%28figure._fig~3alist-box%29%29" data-pltdoc="x"><span class="FigureRef">45</span></a>. Which of the sketches
|
|
do you like better? <a href="part_two.html#%28counter._%28exercise._ex~3alist1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">You can also make lists of numbers. Here is a list with the 10 digits:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">4</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">5</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">6</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">7</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">8</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">To build this list requires 10 list constructions and one
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. For a list of three arbitrary numbers, for 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">e</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-2</span>2.3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">we need three <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>es.</div></p><p><div class="SIntrapara">In general a list does not have to contain values of one kind, but may
|
|
contain arbitrary values:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Robbie Round"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">#true</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first<span class="refelem"><span class="refcolumn"><span class="refcontent">Then again, if this list is supposed to represent a
|
|
record with a fixed number of pieces, use a structure type instead.</span></span></span> item
|
|
of this list is a string, the second one is a number, and the last one a
|
|
Boolean. You may consider this list as the representation of a personnel
|
|
record with three pieces of data: the name of the employee, the number of
|
|
years spent at the company, and whether the employee has health insurance
|
|
through the company. Or, you could think of it as representing a virtual
|
|
player in some game. Without a data definition, you just can’t know what
|
|
data is all about.</div></p><p><div class="SIntrapara">Here is a first data definition that involves <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._3lon)"></a><span style="font-style: italic">3LON</span><span class="RktCmt"> is a list of three numbers: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> a point in 3-dimensional space </span></td></tr></table></blockquote></div><div class="SIntrapara">Of course, this data definition uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> like others use
|
|
constructors for structure instances, and in a sense, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> is
|
|
just a special constructor. What this data definition fails to demonstrate
|
|
is how to form lists of arbitrary length: lists that contain
|
|
nothing, one item, two items, ten items, or perhaps 1,438,901 items.</div></p><p><div class="SIntrapara">So let’s try again:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._name)"></a><span style="font-style: italic">List-of-names</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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"> </span><a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> a list of invitees, by last name</span></td></tr></table></blockquote></div><div class="SIntrapara">Take a deep breath, read it again. This data definition is one
|
|
of the most unusual definitions you have ever encountered—<wbr></wbr>you
|
|
have never before seen a definition that refers to itself. It isn’t
|
|
even clear whether it makes sense. After all, if you had told your
|
|
English teacher that “a table is a table” defines the word “table,”
|
|
the most likely response would have been “Nonsense!” because a
|
|
self-referential definition doesn’t explain what a word means.</div></p><p><div class="SIntrapara">In computer science and in programming, though, self-referential
|
|
definitions play a central role, and with some care, such definitions
|
|
actually do make sense. Here “making sense” means that we can use the
|
|
data definition for what it is intended for, namely, to generate examples of
|
|
data that belong to the class that is being defined or to check
|
|
whether some given piece of data belongs to the defined class of
|
|
data. From this perspective, the definition of <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> makes
|
|
complete sense. At a minimum, we can generate <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> as
|
|
one example, using the first clause in the itemization. Given
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> as an element of <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a>, it is easy to
|
|
make a second one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Findler"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here we are using a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> and the only list from
|
|
<a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> to generate a piece of data according to the second
|
|
clause in the itemization. With the same rule, we can generate many more
|
|
lists of this kind:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Felleisen"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Krishnamurthi"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">And while these lists all contain one name (represented as a
|
|
<a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>), it is actually possible to use the second line of the data
|
|
definition to create lists with more names in them:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Felleisen"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Findler"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">This piece of data belongs to <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> because
|
|
<span class="RktVal">"Felleisen"</span> is a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"Findler"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> is a confirmed <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a>.</div></p><p><a name="(counter._(exercise._ex~3alists))"></a><span style="font-weight: bold">Exercise</span> 130. Create an element of <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> that
|
|
contains five <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s. Sketch a box representation of the list
|
|
similar to those found in <a href="part_two.html#%28counter._%28figure._fig~3abuild-a-list%29%29" data-pltdoc="x">figure <span class="FigureRef">44</span></a>.</p><p><div class="SIntrapara">Explain why
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"1"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"2"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">is an element of <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> and why <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> isn’t. <a href="part_two.html#%28counter._%28exercise._ex~3alists%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3alist7))"></a><span style="font-weight: bold">Exercise</span> 131. Provide a data definition for representing lists of
|
|
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> values. The class contains all arbitrarily long lists of
|
|
<a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>s. <a href="part_two.html#%28counter._%28exercise._ex~3alist7%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>8.2<tt> </tt><a name="(part._sec~3alists-cons)"></a>What Is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, What Is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></h4><p>Let’s step back for a moment and take a close look at <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> and
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>. As mentioned, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is just a constant. When
|
|
compared to constants such as <span class="RktVal">5</span> or <span class="RktVal">"this is a string"</span>,
|
|
it looks more like a function name or a variable; but when compared with
|
|
<span class="RktVal">#true</span> and <span class="RktVal">#false</span>, it should be easy to see that it really
|
|
is just BSL’s representation for empty lists.</p><p><div class="SIntrapara">As for our evaluation rules, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is a new kind of atomic value,
|
|
distinct from any other kind: numbers, Booleans, strings, and so on. It
|
|
also isn’t a compound value, like <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. Indeed, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is
|
|
so unique it belongs in a class of values all by itself. As such, this
|
|
class of values comes with a predicate that recognizes only <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>
|
|
and nothing else:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is the given value </span><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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Like all predicates, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span> can be applied to any value
|
|
from the universe of BSL values. It produces <span class="RktVal">#true</span> precisely
|
|
when it is applied to <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktVal">"hello world"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#false</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Next we turn to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>. Everything we have seen so far suggests that
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> is a constructor just like those introduced by structure
|
|
type definitions. More precisely, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> appears to be the
|
|
constructor for a two-field structure: the first one for any kind of value
|
|
and the second one for any list-like value. The following definitions
|
|
translate this idea into BSL:
|
|
<a name="(idx._(gentag._205))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">pair</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._left%29%29" class="RktStxLink" data-pltdoc="x">left</a></span><span class="hspace"> </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"> </span><span class="RktCmt">A </span><a name="(tech._conspair)"></a><span style="font-style: italic">ConsPair</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="stt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="stt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktPn">)</span><span class="RktCmt">.</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._conspair%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsPair</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace"> </span><span class="RktSym">a-value</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="hspace"> </span><span class="RktSym">a-value</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The only catch is that <span class="RktSym">our-cons</span> accepts all possible BSL values
|
|
for its second argument and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> doesn’t, as the following
|
|
experiment validates:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">cons:second argument must be a list, but received 1 and 2</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Put differently, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> is really a checked function, the kind
|
|
discussed in <a href="part_one.html#%28part._ch~3amix%29" data-pltdoc="x">Itemizations and Structures</a>, which suggests the following refinement:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._consorempty)"></a><span style="font-style: italic">ConsOrEmpty</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="stt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="stt"> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktCmt"> is the class of </span><span style="font-weight: bold">all</span><span class="RktCmt"> lists</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace"> </span><span class="RktSym">a-value</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="hspace"> </span><span class="RktSym">a-value</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">pair?</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="hspace"> </span><span class="RktSym">a-value</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">"cons: second argument ..."</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">If <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> is a checked constructor function, you may be wondering
|
|
how to extract the pieces from the resulting structure. After all,
|
|
<a href="part_one.html#%28part._ch~3astructure%29" data-pltdoc="x">Adding Structure</a> says that programming with structures requires
|
|
selectors. Since a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> structure has two fields, there are two
|
|
selectors: <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>. They are also easily defined
|
|
in terms of our <span class="RktSym">pair</span> structure:
|
|
<a name="(idx._(gentag._206))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._consorempty%29" class="techoutside" data-pltdoc="x"><span class="techinside">ConsOrEmpty</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">extracts the </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="RktCmt"> part of the given </span><span class="RktSym">pair</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-first</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._error%29%29" class="RktValLink" data-pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">our-first</span><span class="hspace"> </span><span class="RktVal">"..."</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">pair-left</span><span class="hspace"> </span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Define <span class="RktSym">our-rest</span>.</div></p><p>If your program can access the structure type definition for <span class="RktSym">pair</span>,
|
|
it is easy to create <span class="RktSym">pair</span>s that don’t contain <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> or
|
|
another <span class="RktSym">pair</span> in 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. Whether such bad
|
|
instances are created intentionally or accidentally, they tend to break
|
|
functions and programs in strange ways. BSL therefore hides the actual
|
|
structure type definition for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> to avoid these
|
|
problems. <a href="part_three.html#%28part._sec~3alocal-definitions%29" data-pltdoc="x">Local Definitions</a> demonstrates one way that your
|
|
programs can hide such definitions, too, but for now, you don’t need this
|
|
power.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote><table cellspacing="0" cellpadding="0"><tr><td align="left"><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>a special value, mostly to represent the empty list</p></td></tr><tr><td align="left"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>a predicate to recognize <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> and nothing else</p></td></tr><tr><td align="left"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>a checked constructor to create two-field instances</p></td></tr><tr><td align="left"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>the selector to extract the last item added</p></td></tr><tr><td align="left"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>the selector to extract the extended list</p></td></tr><tr><td align="left"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span></p></td><td align="left"><p><span class="hspace"> </span></p></td><td align="left"><p>a predicate to recognize instances of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></p></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acons))" x-target-lift="Figure"></a>Figure 46: </span>List primitives</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3acons%29%29" data-pltdoc="x">Figure <span class="FigureRef">46</span></a> summarizes this section. The key insight is that
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is a unique value and that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> is a checked
|
|
constructor that produces list values. Furthermore, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span> are merely distinct names for the usual
|
|
predicate and selectors. What this chapter teaches, then, is <span style="font-weight: bold">not</span> a
|
|
new way of creating data but <span style="font-weight: bold">a new way of formulating data definitions</span>.</p><h4>8.3<tt> </tt><a name="(part._sec~3alists-programming)"></a>Programming with Lists</h4><p><div class="SIntrapara">Say you’re keeping track of your friends with some list, and say the list
|
|
has grown so large that you need a program to determine whether
|
|
some<span class="refelem"><span class="refcolumn"><span class="refcontent">Here we use the word “friend” in the sense of social
|
|
networks, not the real world.</span></span></span> name is on the list. To make this idea
|
|
concrete, let’s state it as an exercise:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> You are working on the contact list for some new cell
|
|
phone. The phone’s owner updates and consults this list on various
|
|
occasions. For now, you are assigned the task of designing a function that
|
|
consumes this list of contacts and determines whether it contains the name
|
|
“Flatt.”</p></blockquote></div><div class="SIntrapara">Once we have a solution to this sample problem, we will generalize it to a
|
|
function that finds any name on a list.</div></p><p><div class="SIntrapara">The data definition for <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a> from the preceding is
|
|
appropriate for representing the list of names that the function is to
|
|
search. Next we turn to the header material: <a name="(idx._(gentag._207))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktVal">"Flatt"</span><span class="RktCmt"> is on </span><span class="RktSym">a-list-of-names</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">a-list-of-names</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">While <span class="RktSym">a-list-of-names</span> is a good name for the list of names that
|
|
the function consumes, it is a mouthful and we therefore shorten it to
|
|
<span class="RktSym">alon</span>.</div></p><p><div class="SIntrapara">Following the general design recipe, we next make up some examples that
|
|
illustrate the purpose of the function. First, we determine the
|
|
output for the simplest input: <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. Since this list does not
|
|
contain any strings, it certainly does not contain <span class="RktVal">"Flatt"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Then we consider lists with a single item. Here are two 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Find"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In the first case, the answer is <span class="RktVal">#false</span> because the single item on the
|
|
list is not <span class="RktVal">"Flatt"</span>; in the second case, the single item is
|
|
<span class="RktVal">"Flatt"</span>, so the answer is <span class="RktVal">#true</span>. Finally, here is a
|
|
more general 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"A"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Again, the answer case must be <span class="RktVal">#true</span> because the list contains
|
|
<span class="RktVal">"Flatt"</span>. Stop! Make a general example for which the answer must be
|
|
<span class="RktVal">#false</span>.</div></p><p>Take a breath. Run the program. The header is a “dummy” definition for
|
|
the function; you have some examples; they have been turned into tests; and
|
|
best of all, some of them actually succeed. They succeed for the wrong
|
|
reason but succeed they do. If things make sense now, read on.</p><p><div class="SIntrapara">The fourth step is to design a function template that matches the data
|
|
definition. Since the data definition for lists of strings has two
|
|
clauses, the function’s body must be a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression with two
|
|
clauses. The two conditions determine which of the two kinds of
|
|
lists the function received:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Instead of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>, we could use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span> in
|
|
the second clause.</div></p><p><div class="SIntrapara">We can add one more hint to the template by studying each clause of the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression in turn. Specifically, recall that the design
|
|
recipe suggests annotating each clause with selector expressions if the
|
|
corresponding class of inputs consists of compounds. In our case, we know
|
|
that <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> does not have compounds, so there are no
|
|
components. Otherwise the list is constructed from a string and
|
|
another list of strings, and we remind ourselves of this fact by adding
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> to
|
|
the 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></p><p><div class="SIntrapara">Now it is time to switch to the programming task proper, the fifth step of
|
|
our design recipe. It starts from a template and deals with each
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause separately. If <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>
|
|
is true, the input is the empty list, in which case the function must
|
|
produce the result <span class="RktVal">#false</span>. In the second case, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is true. The annotations in the template remind us that
|
|
there is a first string and then the rest of the list. So let’s consider an
|
|
example that falls into this category:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"A"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The function, like a person, must compare the first item with
|
|
<span class="RktVal">"Flatt"</span>. In this example, the first one is <span class="RktVal">"A"</span> and not
|
|
<span class="RktVal">"Flatt"</span>, so the comparison yields <span class="RktVal">#false</span>. If we had
|
|
considered some other example instead, say,
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">the function would determine that the first item on the input is
|
|
<span class="RktVal">"Flatt"</span>, and would therefore respond with <span class="RktVal">#true</span>. This
|
|
implies that the second line in the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression should contain
|
|
an expression that compares the first name on the list with
|
|
<span class="RktVal">"Flatt"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Furthermore, if the comparison yields <span class="RktVal">#true</span>, the function must
|
|
produce <span class="RktVal">#true</span>. If the comparison yields <span class="RktVal">#false</span>, we are
|
|
left with another list of strings: <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>. Clearly, the function can’t know the final answer in
|
|
this case, because the answer depends on what “...” represents. Put
|
|
differently, if the first item is not <span class="RktVal">"Flatt"</span>, we need some way
|
|
to check whether the rest of the list contains <span class="RktVal">"Flatt"</span>.</div></p><p>Fortunately, we have <span class="RktSym">contains-flatt?</span> and it fits the bill. According
|
|
to its purpose statement, it determines whether a list contains
|
|
<span class="RktVal">"Flatt"</span>. The statement implies that <span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span>
|
|
tells us whether the list of strings <span class="RktSym">l</span> contains
|
|
<span class="RktVal">"Flatt"</span>. And, in the same vein, <span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span> determines whether <span class="RktVal">"Flatt"</span> is a member of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>,
|
|
which is precisely what we need to know.</p><p><div class="SIntrapara">In short, the last line should be <span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 trick is now to combine the values of the two expressions in the
|
|
appropriate manner. As mentioned, if the first expression yields
|
|
<span class="RktVal">#true</span>, there is no need to search the rest of the list; if it is
|
|
<span class="RktVal">#false</span>, though, the second expression may still yield
|
|
<span class="RktVal">#true</span>, meaning the name <span class="RktVal">"Flatt"</span> is on the rest of the
|
|
list. All of this suggests that the result of <span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is <span class="RktVal">#true</span> if <span style="font-weight: bold">either</span> the first expression in the last line
|
|
<span style="font-weight: bold">or</span> the second expression yields <span class="RktVal">#true</span>.</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"> </span><a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines whether </span><span class="RktVal">"Flatt"</span><span class="RktCmt"> occurs on </span><span class="RktSym">alon</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"X"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Y"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Z"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"A"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acontains-flatt~3f))" x-target-lift="Figure"></a>Figure 47: </span>Searching a list</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3acontains-flatt~3f%29%29" data-pltdoc="x">Figure <span class="FigureRef">47</span></a> then shows the complete definition. Overall
|
|
it doesn’t look too different from the definitions in the first chapter of
|
|
the book. It consists of a signature, a purpose statement, two examples,
|
|
and a definition. The only way in which this function definition differs
|
|
from anything you have seen before is the self-reference, that is, the
|
|
reference to <span class="RktSym">contains-flatt?</span> in the body of the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span>. Then again, the data definition is self-referential, too,
|
|
so in some sense the self-reference in the function shouldn’t be too surprising.</p><p><div class="SIntrapara"><a name="(counter._(exercise._contains-flatt01))"></a><span style="font-weight: bold">Exercise</span> 132. Use DrRacket to run <span class="RktSym">contains-flatt?</span> in 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Fagan"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Findler"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Fisler"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flanagan"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Felleisen"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Friedman"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">What answer do you expect? <a href="part_two.html#%28counter._%28exercise._contains-flatt01%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._contains-flatt02))"></a><span style="font-weight: bold">Exercise</span> 133. Here is another way of formulating the second
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause in
|
|
<span class="RktSym">contains-flatt?</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr></table></blockquote></div><div class="SIntrapara">Explain why this expression produces the same answers as the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span>
|
|
expression in the version of <a href="part_two.html#%28counter._%28figure._fig~3acontains-flatt~3f%29%29" data-pltdoc="x">figure <span class="FigureRef">47</span></a>. Which
|
|
version is clearer to you? Explain. <a href="part_two.html#%28counter._%28exercise._contains-flatt02%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._contains-flatt03))"></a><span style="font-weight: bold">Exercise</span> 134. Develop the <span class="RktSym">contains?</span> function, which
|
|
determines whether some given string occurs on a given list of strings.</p><p><div class="SIntrapara"><span style="font-weight: bold">Note</span> BSL actually comes with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span>, a function that
|
|
consumes two values and checks whether the first occurs in the second,
|
|
a list:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#true</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Don’t use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span> to define the <span class="RktSym">contains?</span> function. <a href="part_two.html#%28counter._%28exercise._contains-flatt03%29%29" class="ex-end" data-pltdoc="x"></a></div></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">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"C"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acomp-cons1))" x-target-lift="Figure"></a>Figure 48: </span>Computing with lists, step 1</span></p></blockquote><h4>8.4<tt> </tt><a name="(part._sec~3aeval-list)"></a>Computing with Lists</h4><p><div class="SIntrapara">Since we are still using BSL, the rules of algebra—<wbr></wbr>see
|
|
intermezzo 1—<wbr></wbr>tell us how to determine the value of expressions such as
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">without DrRacket. Programmers must have an intuitive understanding of how
|
|
this kind of calculation works, so we step through the one for this
|
|
simple example.</div></p><p><a href="part_two.html#%28counter._%28figure._fig~3acomp-cons1%29%29" data-pltdoc="x">Figure <span class="FigureRef">48</span></a> displays the first step, which uses the usual
|
|
substitution rule to determine the value of an application. The result is a
|
|
conditional expression because, as an algebra teacher would say, the
|
|
function is defined in a step-wise fashion.</p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktVal">#false</span></span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"C"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="highlighted"><span class="RktVal">#true</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"C"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acomp-cons2))" x-target-lift="Figure"></a>Figure 49: </span>Computing with lists, step 2</span></p></blockquote><p>The calculation is continued in <a href="part_two.html#%28counter._%28figure._fig~3acomp-cons2%29%29" data-pltdoc="x">figure <span class="FigureRef">49</span></a>. To find the
|
|
correct clause of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression, we must determine the value
|
|
of the conditions, one by one. Since a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed list isn’t empty,
|
|
the first condition’s result is <span class="RktVal">#false</span>, and we therefore eliminate
|
|
the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause. Finally the condition in the second clause
|
|
evaluates to <span class="RktVal">#true</span> because <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span> of a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed
|
|
list holds.</p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="stt"> </span><span class="RktVal">#true</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">#true</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acomp-cons3))" x-target-lift="Figure"></a>Figure 50: </span>Computing with lists, step 3</span></p></blockquote><p>From here, it is just three more steps of arithmetic to get the final
|
|
result. <a href="part_two.html#%28counter._%28figure._fig~3acomp-cons3%29%29" data-pltdoc="x">Figure <span class="FigureRef">50</span></a> displays the three steps. The first
|
|
evaluates <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"Flatt"</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span> to <span class="RktVal">"Flatt"</span> due to
|
|
the laws for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span>. The second discovers that <span class="RktVal">"Flatt"</span> is
|
|
a string and equal to <span class="RktVal">"Flatt"</span>. The third says <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="stt"> </span><span class="RktVal">#true</span><span class="stt"> </span><span class="RktSym">X</span><span class="RktPn">)</span> is
|
|
<span class="RktVal">#true</span> regardless of what <span class="RktSym">X</span> is.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3acontains-step))"></a><span style="font-weight: bold">Exercise</span> 135. Use DrRacket’s stepper to check the
|
|
calculation for
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Also use the stepper to determine the value of
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"A"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Flatt"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"C"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">What happens when <span class="RktVal">"Flatt"</span> is replaced with <span class="RktVal">"B"</span>? <a href="part_two.html#%28counter._%28exercise._ex~3acontains-step%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3amy-cons-step))"></a><span style="font-weight: bold">Exercise</span> 136. Validate with DrRacket’s stepper
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">our-first</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">our-rest</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-cons</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">==</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr></table></blockquote></div><div class="SIntrapara">See <a href="part_two.html#%28part._sec~3alists-cons%29" data-pltdoc="x">What Is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, What Is <span class="RktSym"><span class="RktValLink">cons</span></span></a> for the definitions of these functions. <a href="part_two.html#%28counter._%28exercise._ex~3amy-cons-step%29%29" class="ex-end" data-pltdoc="x"></a></div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_94.png" alt="image" width="210.2578125" height="79.234375"/></p></td><td valign="top"><p><span class="hspace"></span></p></td><td valign="top"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_95.png" alt="image" width="229.1328125" height="127.46875"/></p></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adata-def-arrows))" x-target-lift="Figure"></a>Figure 51: </span>Arrows for self-references in data definitions and templates</span></p></blockquote><h3>9<tt> </tt><a name="(part._ch~3adesign-lists)"></a>Designing with Self-Referential Data Definitions</h3><p><div class="SIntrapara">At first glance, self-referential <a name="(idx._(gentag._208))"></a>data definitions seem to be far more
|
|
complex than those for mixed data. But, as the example of
|
|
<span class="RktSym">contains-flatt?</span> shows, the six steps of the design recipe still
|
|
work. Nevertheless, in this section we generalize the design recipe so that
|
|
it works even better for <a name="(idx._(gentag._209))"></a>self-referential data definitions. The new parts
|
|
concern the process of discovering when a self-referential data definition
|
|
is needed, deriving a template, and defining the function body:
|
|
</div><div class="SIntrapara"><ol><li><p>If a problem statement is about information of arbitrary size, you
|
|
need a <a name="(idx._(gentag._210))"></a>self-referential data definition to represent it. At this point,
|
|
you have seen only one such class, <a href="part_two.html#%28tech._list._of._name%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-names</span></a>. The left side of
|
|
<a href="part_two.html#%28counter._%28figure._fig~3adata-def-arrows%29%29" data-pltdoc="x">figure <span class="FigureRef">51</span></a> shows how to define
|
|
<a name="(tech._list._of._string)"></a><span style="font-style: italic">List-of-strings</span> in the same way. Other lists of atomic data work
|
|
the same way.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Numbers also seem to be arbitrarily large. For inexact
|
|
numbers, this is an illusion. For precise integers, this is indeed the
|
|
case. Dealing with integers is therefore a part of this chapter.</p></blockquote></blockquote></blockquote><p>For a self-referential data definition to be valid, it must satisfy two
|
|
conditions. First, it must contain at least two clauses. Second, at least
|
|
one of the clauses must not refer back to the class of data that is being
|
|
defined. It is good practice to identify the self-references explicitly with
|
|
arrows from the references in the data definition back to the term being
|
|
defined; see <a href="part_two.html#%28counter._%28figure._fig~3adata-def-arrows%29%29" data-pltdoc="x">figure <span class="FigureRef">51</span></a> for an example of such an
|
|
annotation.</p><p><div class="SIntrapara">You must check the validity of self-referential data definitions with the
|
|
creation of <a name="(idx._(gentag._211))"></a>data examples. Start with the clause that does not refer to the data
|
|
definition; continue with the other one, using the first example where the
|
|
clause refers to the definition itself. For the data
|
|
definition in <a href="part_two.html#%28counter._%28figure._fig~3adata-def-arrows%29%29" data-pltdoc="x">figure <span class="FigureRef">51</span></a>, you thus get lists like
|
|
the following three:
|
|
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><p>by the first clause</p></td></tr><tr><td valign="top"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><p>by the second clause, previous example</p></td></tr><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><p>by the second clause, previous example</p></td></tr></table></div><div class="SIntrapara">If it is impossible to generate <a name="(idx._(gentag._212))"></a>examples from the <a name="(idx._(gentag._213))"></a>data definition, it is
|
|
invalid. If you can generate examples but you can’t see how to generate
|
|
increasingly larger examples, the definition may not live up to its
|
|
interpretation.</div></p></li><li><p>Nothing changes about the header material: the
|
|
<a name="(idx._(gentag._214))"></a>signature, the <a name="(idx._(gentag._215))"></a>purpose statement, and
|
|
the dummy definition. When you do formulate the purpose statement, focus
|
|
on <span style="font-weight: bold">what</span> the function computes <span style="font-weight: bold">not how</span> it goes about it,
|
|
especially not how it goes through instances of the given data.</p><p><div class="SIntrapara">Here is an example to make this design recipe concrete: <a name="(idx._(gentag._216))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">counts how many strings </span><span class="RktSym">alos</span><span class="RktCmt"> contains </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <a name="(idx._(gentag._217))"></a>purpose statement clearly states that the function just counts the
|
|
strings on the given input; there is no need to think ahead about how you
|
|
might formulate this idea as a BSL function.</div></p></li><li><p>When it comes to <a name="(idx._(gentag._218))"></a>functional examples, be sure to work through inputs
|
|
that use the self-referential clause of the data definition several
|
|
times. It is the best way to formulate tests that cover the entire
|
|
function definition later.</p><p><div class="SIntrapara">For our running example, the purpose statement almost generates functional
|
|
examples by itself from the data examples:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><p>given</p></td><td><p><span class="hspace"> </span></p></td><td><p>wanted</p></td></tr><tr><td><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">0</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </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></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">1</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </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><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">2</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The first row is about the empty list, and we know that empty
|
|
list contains nothing. The second row is a list of one string, so
|
|
<span class="RktVal">1</span> is the desired answer. The last row is about a list of two
|
|
strings.</div></p></li><li><p>At the core, a <a name="(idx._(gentag._219))"></a>self-referential data definition looks like a data
|
|
definition for mixed data. The development of the <a name="(idx._(gentag._220))"></a>template can therefore
|
|
proceed according to the <a name="(idx._(gentag._221))"></a>recipe in <a href="part_one.html#%28part._ch~3amix%29" data-pltdoc="x">Itemizations and Structures</a>. Specifically, we
|
|
formulate a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression with as many <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses as
|
|
there are clauses in the data definition, match each recognizing condition
|
|
to the corresponding clause in the data definition, and write down
|
|
appropriate selector expressions in all <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> lines that process
|
|
compound values.</p><blockquote class="Figure"><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">Question</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">Answer</span></p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>Does the data definition distinguish among different sub-classes of data?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Your template needs as many <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses as sub-classes that
|
|
the data definition distinguishes.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>How do the sub-classes differ from each other?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Use the differences to formulate a condition per clause.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>Do any of the clauses deal with structured values?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>If so, add appropriate selector expressions to the clause.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>Does the data definition use self-references?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Formulate “natural recursions” for the template to represent the
|
|
self-references of the data definition.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">If the data definition refers to some other data definition,</span>
|
|
where is this cross-reference to another data definition?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Specialize the template for the other data definition. Refer to this
|
|
template. See <a href="part_one.html#%28part._mix._sec~3aitemization-design2%29" data-pltdoc="x">Designing with Itemizations, Again</a>,
|
|
steps 4 and 5 of the design recipe.</p></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3atemplate-q))" x-target-lift="Figure"></a>Figure 52: </span>How to translate a data definition into a template</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">Figure <span class="FigureRef">52</span></a> expresses this idea as a question-and-answer
|
|
game. In the left column it states questions about the data definition for
|
|
the argument, and in the right column it explains what the answer means for
|
|
the construction of the template.</p><p><div class="SIntrapara">If you ignore the last row and apply the first three questions to any
|
|
function that consumes a <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a>, you arrive at this shape:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fun-for-los</span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></p><p>Recall, though, that the purpose of a <a name="(idx._(gentag._222))"></a>template is to express the data
|
|
definition as a function layout. That is, a template expresses as code what
|
|
the data definition for the input expresses as a mix of English and
|
|
BSL. Hence all important pieces of the data definition must find a
|
|
counterpart in the template, and this guideline should also hold when a
|
|
data definition is self-referential—<wbr></wbr>contains an arrow from inside the
|
|
definition to the term being defined. In particular, when a data definition
|
|
is self-referential in the <span style="font-style: italic">i</span>th clause and the <span style="font-style: italic">k</span>th field of
|
|
the structure mentioned there, the template should be self-referential in
|
|
the <span style="font-style: italic">i</span>th <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause and the selector expression for the
|
|
<span style="font-style: italic">k</span>th field. For each such selector expression, add an arrow back to
|
|
the function parameter. At the end, your template must have as many arrows
|
|
as we have in the data definition.</p><p><a href="part_two.html#%28counter._%28figure._fig~3adata-def-arrows%29%29" data-pltdoc="x">Figure <span class="FigureRef">51</span></a> illustrates this idea with the template
|
|
for functions that consume <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a> shown side by side with
|
|
the data definition. Both contain one arrow that
|
|
originates in the second clause—<wbr></wbr>the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field and selector,
|
|
respectively—<wbr></wbr>and points back to the top of the respective definitions.</p><p><div class="SIntrapara">Since BSL and most programming languages are text-oriented, you must use
|
|
an alternative to the arrow, namely, a self-application of the function to the
|
|
appropriate selector expression:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fun-for-los</span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fun-for-los</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">We refer to a self-use of a function as <span style="font-style: italic">recursion</span> and in the
|
|
first four parts of the book as <span style="font-style: italic">natural recursion</span>.</div></p></li><li><p>For the function body we start with those<span class="refelem"><span class="refcolumn"><span class="refcontent">For the
|
|
curious among our readers, the design recipe for arbitrarily large data
|
|
corresponds to so-called <a name="(idx._(gentag._223))"></a>“proofs by induction” in mathematics, and the
|
|
“leap of faith” represents the use of the induction hypothesis
|
|
for the inductive step of such a proof. Logic proves the
|
|
validity of this proof technique with an Induction Theorem.</span></span></span>
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> lines without recursive function calls, known as
|
|
<span style="font-style: italic">base cases</span>.The corresponding answers are typically easy
|
|
to formulate or already given as examples.</p><p>Then we deal with the self-referential cases. We start by reminding
|
|
ourselves what each of the expressions in the template line computes. For
|
|
the natural recursion we assume that the function already works as
|
|
specified in our <a name="(idx._(gentag._224))"></a>purpose statement. This last step is a leap of faith, but
|
|
as you will see, it always works.</p><p><span style="font-weight: bold">The rest is then a matter of combining the various values.</span></p><blockquote class="Figure"><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">Question</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">Answer</span></p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>What are the answers for the non-recursive <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>The examples should tell you which values you need here. If not,
|
|
formulate appropriate examples and tests.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>What do the selector expressions in the recursive clauses compute?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>The data definitions tell you what kind of data these expressions
|
|
extract, and the interpretations of the data definitions tell you what
|
|
this data represents.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>What do the natural recursions compute?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Use the purpose statement of the function to determine what the
|
|
value of the recursion means, <span style="font-weight: bold">not how it computes this answer</span>. If
|
|
the purpose statement doesn’t tell you the answer, improve the purpose
|
|
statement.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>How can the function combine these values to get the desired answer?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Find a function in BSL that combines the values. Or, if that
|
|
doesn’t work, make a wish for a helper function. For many functions, this
|
|
last step is straightforward. The purpose, the examples, and the template
|
|
together tell you which function or expression <span style="font-weight: bold">combines</span> the available
|
|
values into the proper result. We refer to this function or expression as a
|
|
<span style="font-style: italic">combinator</span>, slightly abusing existing terminology.</p></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adefinition-q))" x-target-lift="Figure"></a>Figure 53: </span>How to turn a template into a function definition</span></p></blockquote><blockquote class="Figure"><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">Question</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">Answer</span></p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">So, if you are stuck here, ...</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>... arrange the examples from the third step in a table.
|
|
Place the given input in the first column and the desired output
|
|
in the last column. In the intermediate columns enter the values of the
|
|
selector expressions and the natural recursion(s). Add examples until you
|
|
see a pattern emerge that suggests a combinator.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">If the template refers to some other template,</span>
|
|
what does the auxiliary function compute?</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Consult the other function’s purpose statement and examples to
|
|
determine what it computes, and assume you may use the result even if you
|
|
haven’t finished the design of this helper function.</p></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adefinition-qb))" x-target-lift="Figure"></a>Figure 54: </span>Turning a template into a function, the table method</span></p></blockquote><p><div class="SIntrapara"><a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">Figure <span class="FigureRef">53</span></a> formulates the first four questions and
|
|
answers for this step. Let’s use this game to complete the definition of
|
|
<span class="RktSym">how-many</span>. Renaming the <span class="RktSym">fun-for-los</span> template to <span class="RktSym">how-many</span>
|
|
gives us this much:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines how many strings are on </span><span class="RktSym">alos</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">As the functional examples already suggest, the answer for the base case
|
|
is <span class="RktVal">0</span>. The two expressions in the second clause compute the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> item and the number of strings in <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span>. To
|
|
compute how many strings there are on all of <span class="RktSym">alos</span>, the function just needs
|
|
to add <span class="RktVal">1</span> to the value of the latter expression:<a name="(idx._(gentag._225))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Felix Klock suggested this table-based approach to
|
|
guessing the combinator.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">Finding the correct way to combine the values into the desired answer isn’t
|
|
always as easy. Novice programmers often get stuck with this step. As <a href="part_two.html#%28counter._%28figure._fig~3adefinition-qb%29%29" data-pltdoc="x">figure <span class="FigureRef">54</span></a>
|
|
suggests, it is a good idea to arrange the
|
|
<a name="(idx._(gentag._226))"></a>functional examples into a <a name="(idx._(gentag._227))"></a>table that also spells out the values of the
|
|
expressions in the template. <a href="part_two.html#%28counter._%28figure._fig~3afelix-table1%29%29" data-pltdoc="x">Figure <span class="FigureRef">55</span></a> shows what this
|
|
table looks like for our <span class="RktSym">how-many</span> example. The left-most column
|
|
lists the sample inputs, while the right-most column contains the desired
|
|
answers for these inputs. The three columns in between show the values of
|
|
the template expressions: <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span>, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span>, and <span class="RktPn">(</span><span class="RktSym">how-many</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span>, which is the natural
|
|
recursion. If you stare at this table long enough, you recognize that the
|
|
result column is always one more than the values in the natural recursion
|
|
column. You may thus guess that
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">is the expression that computes the desired result. Since DrRacket is fast at
|
|
checking these kinds of guesses, plug it in and click <span class="emph">RUN</span>. If the
|
|
examples-turned-into-tests pass, think through the expression to convince
|
|
yourself it works for all lists; otherwise add more example rows to the
|
|
table until you have a different idea.</div></p><p>The table also points out that some selector expressions in the template
|
|
are possibly irrelevant for the actual definition. Here <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alos</span><span class="RktPn">)</span> is not needed to compute the final answer—<wbr></wbr>which is quite a contrast
|
|
to <span class="RktSym">contains-flatt?</span>, which uses both expressions from the template.</p><p>As you work your way through the rest of this book, keep in mind that, in
|
|
many cases, the combination step can be expressed with BSL’s primitives,
|
|
say, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span>, or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>. In some cases, though, you
|
|
may have to make a wish, that is, design an auxiliary function. Finally, in
|
|
yet other cases, you may need nested conditions.</p></li><li><p>Finally, make sure to turn all examples into tests, that these tests
|
|
pass, and that running them covers all the pieces of the function.</p><p><div class="SIntrapara">Here are our examples for <span class="RktSym">how-many</span> turned into 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Remember, it is best to formulate examples directly as tests, and BSL
|
|
allows this. Doing so also helps if you need to resort to the table-based
|
|
guessing approach of the preceding step.</div></p></li></ol></div></p><blockquote class="Figure"><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;"><span class="RktSym">alos</span></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr></table></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr></table></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">how-many</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">how-many</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">alos</span><span class="RktPn">)</span></td></tr></table></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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">"a"</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">0</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">1</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">"b"</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">1</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">2</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"x"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">"x"</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">2</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">3</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3afelix-table1))" x-target-lift="Figure"></a>Figure 55: </span>Tabulating arguments, intermediate values, and results</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3adesign5%29%29" data-pltdoc="x">Figure <span class="FigureRef">56</span></a> summarizes the <a name="(idx._(gentag._228))"></a>design recipe of this section in a
|
|
tabular format. The first column names the steps of the design recipe, and
|
|
the
|
|
second the expected results of each step. In the third column, we describe
|
|
the activities that get you there.<span class="refelem"><span class="refcolumn"><span class="refcontent">You may want to copy
|
|
<a href="part_two.html#%28counter._%28figure._fig~3adesign5%29%29" data-pltdoc="x">figure <span class="FigureRef">56</span></a> onto one side of an index card and write down
|
|
your favorite versions of the questions and answers for this design recipe
|
|
onto the back of it. Then carry it with you for future reference.</span></span></span> The
|
|
figure is tailored to the kind of self-referential list definitions we use
|
|
in this chapter. As always, practice helps you master the process, so we
|
|
strongly recommend that you tackle the following exercises, which ask you
|
|
to apply the recipe to several kinds of examples.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><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">steps</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">outcome</span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p><span style="font-weight: bold">activity</span></p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>problem analysis</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>data definition</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Develop a <a name="(idx._(gentag._229))"></a>data representation for the information;
|
|
create examples for specific items of information
|
|
and interpret data as information;
|
|
identify self-references.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>header</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>signature; purpose; dummy definition</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Write down a signature using defined names;
|
|
formulate a concise purpose statement;
|
|
create a dummy function that produces a constant value from the specified range.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>examples</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>examples and tests</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Work through several examples, at least one per
|
|
clause in the data definition.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>template</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>function template</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Translate the data definition into a template:
|
|
one <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause per data clause;
|
|
selectors where the condition identifies a structure;
|
|
one natural recursion per self-reference.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>definition</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>full-fledged definition</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Find a function that combines the values of the expressions in the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
|
|
clauses into the expected answer.</p></td></tr><tr><td align="left" style="border-bottom: 1px solid black;"><p>test</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>validated tests</p></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><p>Turn them into <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> tests and run them.</p></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adesign5))" x-target-lift="Figure"></a>Figure 56: </span>Designing a function for self-referential data</span></p></blockquote><h4>9.1<tt> </tt><a name="(part._sec~3afinger-lists)"></a>Finger Exercises: Lists</h4><p><a name="(counter._(exercise._list0))"></a><span style="font-weight: bold">Exercise</span> 137. Compare the template for <span class="RktSym">contains-flatt?</span> with
|
|
the one for <span class="RktSym">how-many</span>. Ignoring the function name, they are the
|
|
same. Explain the similarity. <a href="part_two.html#%28counter._%28exercise._list0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._list-sum1))"></a><span style="font-weight: bold">Exercise</span> 138. Here is a data definition for representing sequences
|
|
of amounts of money:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._amount)"></a><span style="font-style: italic">List-of-amounts</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._positivenumber%29" class="techoutside" data-pltdoc="x"><span class="techinside">PositiveNumber</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list._of._amount%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-amounts</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Create some examples to make sure you understand the data definition. Also add
|
|
an arrow for the self-reference.</div></p><p>Design the <span class="RktSym">sum</span> function, which consumes a <a href="part_two.html#%28tech._list._of._amount%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-amounts</span></a>
|
|
and computes the sum of the amounts. Use DrRacket’s stepper to see how
|
|
<span class="RktPn">(</span><span class="RktSym">sum</span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> works for a short list <span class="RktSym">l</span> in
|
|
<a href="part_two.html#%28tech._list._of._amount%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-amounts</span></a>. <a href="part_two.html#%28counter._%28exercise._list-sum1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._list-sum2))"></a><span style="font-weight: bold">Exercise</span> 139. Now take a look at this data definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._number)"></a><span style="font-style: italic">List-of-numbers</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Some elements of this class of data are appropriate inputs for <span class="RktSym">sum</span> from
|
|
<a href="part_two.html#%28counter._%28exercise._list-sum1%29%29" data-pltdoc="x">exercise 138</a> and some aren’t.</div></p><p>Design the function <span class="RktSym">pos?</span>, which consumes a <a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>
|
|
and determines whether all numbers are positive numbers. In other words,
|
|
if <span class="RktPn">(</span><span class="RktSym">pos?</span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> yields <span class="RktVal">#true</span>, then <span class="RktSym">l</span> is an element
|
|
of <a href="part_two.html#%28tech._list._of._amount%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-amounts</span></a>. Use DrRacket’s stepper to understand how
|
|
<span class="RktSym">pos?</span> works for <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>.</p><p>Also design <span class="RktSym">checked-sum</span>. The function consumes a
|
|
<a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>. It produces their sum if the input also belongs to
|
|
<a href="part_two.html#%28tech._list._of._amount%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-amounts</span></a>; otherwise it signals an error. <span style="font-weight: bold">Hint</span> Recall
|
|
to use check-error.</p><p>What does <span class="RktSym">sum</span> compute for an element of <a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>? <a href="part_two.html#%28counter._%28exercise._list-sum2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._list-and))"></a><span style="font-weight: bold">Exercise</span> 140. Design the function <span class="RktSym">all-true</span>, which consumes
|
|
a list of <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> values and determines whether all of them are
|
|
<span class="RktVal">#true</span>. In other words, if there is any <span class="RktVal">#false</span> on the
|
|
list, the function produces <span class="RktVal">#false</span>.</p><p>Now design <span class="RktSym">one-true</span>, a function that consumes a list of Boolean
|
|
values and determines whether at least one item on the list is
|
|
<span class="RktVal">#true</span>. <a href="part_two.html#%28counter._%28exercise._list-and%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Employ the table-based approach to coding. It may help with the base case.
|
|
Use DrRacket’s stepper to see how these functions process the lists
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#true</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>, and
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span>.</p><p><div class="SIntrapara"><a name="(counter._(exercise._list-string))"></a><span style="font-weight: bold">Exercise</span> 141. If you are asked to design the function
|
|
<span class="RktSym">cat</span>, which consumes a list of strings and appends them all into
|
|
one long string, you are guaranteed to end up with this partial
|
|
definition: <a name="(idx._(gentag._230))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-string</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">concatenates all strings in </span><span class="RktSym">l</span><span class="RktCmt"> into one long string</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">""</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"ab"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"ab"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"cd"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"ef"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"abcdef"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">""</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></p><blockquote class="Figure"><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;"><span class="RktSym">l</span></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td><td align="left" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="left" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym">cat</span><span class="hspace"> </span><span class="RktSym">l</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">"ab"</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"ab"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"cd"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"ef"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktSym">???</span></td><td align="left" valign="top"><p><span class="hspace"> </span></p></td><td align="left" valign="top"><span class="RktVal">"abcdef"</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3atable))" x-target-lift="Figure"></a>Figure 57: </span>A table for <span class="RktSym">cat</span></span></p></blockquote><p>Fill in the table in <a href="part_two.html#%28counter._%28figure._fig~3aex~3atable%29%29" data-pltdoc="x">figure <span class="FigureRef">57</span></a>. Guess a function that can
|
|
create the desired result from the values computed by the sub-expressions.</p><p>Use DrRacket’s stepper to evaluate <span class="RktPn">(</span><span class="RktSym">cat</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </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><span class="RktPn">)</span>. <a href="part_two.html#%28counter._%28exercise._list-string%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3alist-image))"></a><span style="font-weight: bold">Exercise</span> 142. Design the <span class="RktSym">ill-sized?</span> function, which consumes a
|
|
list of images <span class="RktSym">loi</span> and a positive number <span class="RktSym">n</span>. It produces
|
|
the first image on <span class="RktSym">loi</span> that is not an <span class="RktSym">n</span> by <span class="RktSym">n</span>
|
|
square; if it cannot find such an image, it produces <span class="RktVal">#false</span>.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hint</span> Use
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">ImageOrFalse is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> Image</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> #false </span></td></tr></table></blockquote></div><div class="SIntrapara">for the result part of the signature. <a href="part_two.html#%28counter._%28exercise._ex~3alist-image%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>9.2<tt> </tt><a name="(part._sec~3alists~3ane)"></a>Non-empty Lists</h4><p>Now you know enough to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and to create data definitions for
|
|
lists. If you solved (some of) the exercises at the end of the preceding
|
|
section, you can deal with lists of various flavors of numbers, lists of
|
|
Boolean values, lists of images, and so on. In this section we continue to explore
|
|
what lists are and how to process them.</p><p><div class="SIntrapara">Let’s start with the simple-looking problem of computing the average of a list
|
|
of temperatures. To simplify, we provide the data definitions:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._temperature)"></a><span style="font-style: italic">List-of-temperatures</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._ctemperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">CTemperature</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ABSOLUTE0</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-2</span>72</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._ctemperature)"></a><span style="font-style: italic">CTemperature</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> greater than </span><span class="RktSym">ABSOLUTE0</span><span class="RktCmt">.</span></td></tr></table></blockquote></div><div class="SIntrapara">For our intentions, you should think of temperatures as plain numbers, but the
|
|
second data definition reminds you that in reality not all numbers are
|
|
temperatures and you should keep this in mind.</div></p><p><div class="SIntrapara">The header material is straightforward: <a name="(idx._(gentag._231))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the average temperature </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Making up examples for this problem is also easy, and so we just formulate
|
|
one test:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The expected result is of course the sum of the temperatures divided by the
|
|
number of temperatures.</div></p><p><div class="SIntrapara">A moment’s thought tells you that the template for average should
|
|
be similar to the ones we have seen so far:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 two <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses mirror the two clauses of the
|
|
data definition; the questions distinguish empty lists from non-empty
|
|
lists; and the natural recursion is needed because of the self-reference
|
|
in the data definition.</div></p><p>It is way too difficult, however, to turn this template into a function
|
|
definition. The first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause needs a number that represents
|
|
the average of an empty collection of temperatures, but there is no such
|
|
number. Similarly, the second clause demands a function that combines a
|
|
temperature and an average for the remaining temperatures into a new
|
|
average. Although possible, computing the average in this way is highly
|
|
unnatural.</p><p><div class="SIntrapara">When we compute the average of temperatures, we divide their sum
|
|
by their number. We said so when we formulated our trivial
|
|
little example. This sentence suggests that <span class="RktSym">average</span> is
|
|
a function of three tasks: summing, counting, and dividing. Our guideline
|
|
from <a href="part_one.html" data-pltdoc="x">Fixed-Size Data</a> tells us to write one function per task, and if
|
|
we do so the design of average is obvious: <a name="(idx._(gentag._232))"></a> <a name="(idx._(gentag._233))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the average temperature </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds up the temperatures on the given list </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">counts the temperatures on the given list </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The last two function definitions are wishes, of course, for which we need <a name="(idx._(gentag._234))"></a>
|
|
to design complete definitions. Doing so is easy because
|
|
<span class="RktSym">how-many</span> from above works for <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a> and
|
|
<a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a> (why?) and because the design of <span class="RktSym">sum</span>
|
|
follows the same old routine:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds up the temperatures on the given list </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alot</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Use the example for <span class="RktSym">average</span> to create one for <span class="RktSym">sum</span>
|
|
and ensure that the test runs properly. Then run the tests
|
|
for <span class="RktSym">average</span>.</div></p><p>When you read this definition of average now, it is obviously correct
|
|
simply because it directly corresponds to what everyone learns about
|
|
averaging in school. Still, programs run not just for us but for others. In
|
|
particular, others should be able to read the signature and use the function
|
|
and expect an informative answer. But, our definition of <span class="RktSym">average</span>
|
|
does not work for empty lists of temperatures.</p><p><a name="(counter._(exercise._average-0))"></a><span style="font-weight: bold">Exercise</span> 143. Determine how <span class="RktSym">average</span> behaves in DrRacket when
|
|
applied to the empty list. Then design
|
|
<span class="RktSym">checked-average</span>, a function that produces an informative error
|
|
message when it is applied to <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. <a href="part_two.html#%28counter._%28exercise._average-0%29%29" class="ex-end" data-pltdoc="x"></a></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>In mathematics, we would say <a href="part_two.html#%28counter._%28exercise._average-0%29%29" data-pltdoc="x">exercise 143</a> shows that
|
|
<span class="RktSym">average</span> is a <span style="font-style: italic">partial function</span> because it raises an error
|
|
for <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">An alternative solution is to inform future readers through the signature that
|
|
<span class="RktSym">average</span> doesn’t work for empty lists. For that, we need a
|
|
data representation for lists that excludes <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, something like this:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><span style="font-style: italic">NEList-of-temperatures</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> ???</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._ctemperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">CTemperature</span></a><span class="stt"> </span><a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The question is with what we should replace “???” so that
|
|
the <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> list is excluded but all other lists of temperatures
|
|
are still constructable. One hint is that while the empty list is the
|
|
shortest list, any list of one temperature is the next shortest list. In
|
|
turn, this suggests that the first clause should describe all possible
|
|
lists of one temperature:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._nelist._of._temperature)"></a><span style="font-style: italic">NEList-of-temperatures</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._ctemperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">CTemperature</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._ctemperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">CTemperature</span></a><span class="stt"> </span><a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> non-empty lists of Celsius temperatures </span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">While this definition differs from the preceding list definitions, it
|
|
shares the critical elements: a self-reference and a clause that does
|
|
<span style="font-weight: bold">not</span> use a self-reference. Strict adherence to the design recipe
|
|
demands that you make up some examples of <a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a> to
|
|
ensure that the definition makes sense. As always, you should start with
|
|
the base clause, meaning the example must look like this:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">where <span class="RktSym">c</span> stands for a <span class="RktSym">CTemperature</span>, like thus:
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">ABSOLUTE0</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>. Also, it is clear that all
|
|
non-empty elements of <a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a> are also elements of the
|
|
new class of data: <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span> fits the bill if <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span> does, and
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span> belongs to <a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a>
|
|
because <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span> is an element of
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a>, as confirmed before. Check for yourself
|
|
that there is no limit on the size of <span class="RktSym">NEList-of-temperatures</span>.</div></p><p><div class="SIntrapara">Let’s now return to the problem of designing <span class="RktSym">average</span> so that
|
|
everyone knows it is for non-empty lists only. With the definition of
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a>, we now have the means to say what we want in
|
|
the signature:<span class="refelem"><span class="refcolumn"><span class="refcontent">This alternative development explains that, in
|
|
this case, we can narrow down the domain of <span class="RktSym">average</span> and create a
|
|
<span style="font-style: italic">total function</span>.</span></span></span> <a name="(idx._(gentag._235))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the average temperature </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">average</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Naturally the rest remains the same: the purpose statement, the
|
|
example-test, and the function definition. After all, the very idea of
|
|
computing the average assumes a non-empty collection of numbers, and that
|
|
was the entire point of our discussion.</div></p><p><a name="(counter._(exercise._nelist2))"></a><span style="font-weight: bold">Exercise</span> 144. Will <span class="RktSym">sum</span> and <span class="RktSym">how-many</span> work for
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a> even though they are designed for inputs from
|
|
<a href="part_two.html#%28tech._list._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-temperatures</span></a>? If you think they don’t work, provide
|
|
counter-examples. If you think they would, explain why. <a href="part_two.html#%28counter._%28exercise._nelist2%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Nevertheless, the definition also raises the question how to design
|
|
<span class="RktSym">sum</span> and <span class="RktSym">how-many</span> because they consume instances of
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a> now. Here is the obvious result of the first three
|
|
steps of the design recipe:</p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the sum of the given temperatures </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">6</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The example is adapted from the example for <span class="RktSym">average</span>; the dummy
|
|
definition produces a number, but the wrong one for the given test.</div></p><p><div class="SIntrapara">The fourth step is the most interesting part of the design of <span class="RktSym">sum</span> for
|
|
<span class="RktSym">NEList-of-temperatures</span>. All preceding examples of design demand a
|
|
template that distinguishes empty lists from non-empty, that is, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed,
|
|
lists because the data definitions have an appropriate shape. This is not true for
|
|
<span class="RktSym">NEList-of-temperatures</span>. Here both clauses add <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed lists. The
|
|
two clauses differ, however, in the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field of these lists. In
|
|
particular, the first clause always uses <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> in the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field
|
|
and the second one uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> instead. Hence the proper condition
|
|
to distinguish the first kind of data from the second extracts the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> field and then uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Here <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span> replaces <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span>.</div></p><p><div class="SIntrapara">Next you should inspect both clauses and determine whether one or both of them deal
|
|
with <span class="RktSym">ne-l</span> as if it were a structure. This is of course the case, which
|
|
the unconditional use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> on <span class="RktSym">ne-l</span> demonstrates. Put
|
|
differently, add appropriate selector expressions to the two clauses: <a name="(idx._(gentag._236))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Before you read on, explain why the first clause does not contain the selector
|
|
expression <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span>.</div></p><p><div class="SIntrapara">The final question of the template design concerns self-references in the data
|
|
definition. As you know, <span class="RktSym">NEList-of-temperatures</span> contains one, and therefore
|
|
the template for <span class="RktSym">sum</span> demands one recursive use:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Specifically, <span class="RktSym">sum</span> is called on <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span> in the second
|
|
clause because the data definition is self-referential at the analogous point.</div></p><p><div class="SIntrapara">For the fifth design step, let’s understand how much we already
|
|
have. Since the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause looks significantly simpler
|
|
than the second one with its recursive function call, you should start
|
|
with that one. In this particular case, the condition says that
|
|
<span class="RktSym">sum</span> is applied to a list with exactly one temperature,
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span>. Clearly, this one temperature is the sum of all
|
|
temperatures on the given list:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 second clause says that the list consists of a temperature and at
|
|
least one more; <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span> extracts the first
|
|
position and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span> the remaining ones. Furthermore, the
|
|
template suggests to use the result of <span class="RktPn">(</span><span class="RktSym">sum</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span>. But
|
|
<span class="RktSym">sum</span> is the function that you are defining, and you can’t possibly
|
|
know <span style="font-weight: bold">how</span> it uses <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span>. All you do know is what
|
|
the purpose statement says, namely, that <span class="RktSym">sum</span> adds all the
|
|
temperatures on the given list, which is <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span>. If this
|
|
statement is true, then
|
|
<span class="RktPn">(</span><span class="RktSym">sum</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span> adds up all but one of the numbers of
|
|
<span class="RktSym">ne-l</span>. To get the total, the function just has to add the first
|
|
temperature:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sum</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ne-l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you now run the test for this function, you will see that the
|
|
leap of faith is justified. Indeed, for reasons beyond the scope of this
|
|
book, this leap is <span style="font-weight: bold">always</span> justified, which is why it is an inherent
|
|
part of the design recipe.</div></p><p><a name="(counter._(exercise._nelist4))"></a><span style="font-weight: bold">Exercise</span> 145. Design the <span class="RktSym">sorted>?</span> predicate, which consumes a
|
|
<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a> and produces <span class="RktVal">#true</span> if the
|
|
temperatures are sorted in descending order. That is, if the second is
|
|
smaller than the first, the third smaller than the second, and so
|
|
on. Otherwise it produces <span class="RktVal">#false</span>.</p><p><span style="font-weight: bold">Hint</span> This problem is another one where the table-based method for
|
|
guessing the combinator works well. Here is a partial table for a number of
|
|
examples in <a href="part_two.html#%28counter._%28figure._fig~3asorted%29%29" data-pltdoc="x">figure <span class="FigureRef">58</span></a>. Fill in the rest of the table. Then
|
|
try to create an expression that computes the result from the pieces. <a href="part_two.html#%28counter._%28exercise._nelist4%29%29" class="ex-end" data-pltdoc="x"></a></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="center" style="border-bottom: 1px solid black;"><span class="RktSym">l</span></td><td align="center" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="center" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td><td align="center" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="center" style="border-bottom: 1px solid black;"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td><td align="center" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="center" style="border-bottom: 1px solid black;"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">sorted>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="center" style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td align="center" style="border-bottom: 1px solid black;"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">sorted>?</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td align="center"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">1</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktSym">???</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">#true</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">#false</span></td></tr><tr><td align="center"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">3</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktSym">???</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">#true</span></td></tr><tr><td align="center"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktVal">0</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktSym">???</span></td><td align="center"><p><span class="hspace"> </span></p></td><td align="center"><span class="RktSym">???</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asorted))" x-target-lift="Figure"></a>Figure 58: </span>A table for <span class="RktSym">sorted>?</span></span></p></blockquote><p><a name="(counter._(exercise._nelist0))"></a><span style="font-weight: bold">Exercise</span> 146. Design <span class="RktSym">how-many</span> for <a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a>.
|
|
Doing so completes <span class="RktSym">average</span>, so ensure that <span class="RktSym">average</span>
|
|
passes all of its tests, too. <a href="part_two.html#%28counter._%28exercise._nelist0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._nelist1))"></a><span style="font-weight: bold">Exercise</span> 147. Develop a data definition for
|
|
<a name="(tech._nelist._of._boolean)"></a><span style="font-style: italic">NEList-of-Booleans</span>, a representation of non-empty lists of
|
|
Boolean values. Then redesign the functions <span class="RktSym">all-true</span> and
|
|
<span class="RktSym">one-true</span> from <a href="part_two.html#%28counter._%28exercise._list-and%29%29" data-pltdoc="x">exercise 140</a>. <a href="part_two.html#%28counter._%28exercise._nelist1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._nelist3))"></a><span style="font-weight: bold">Exercise</span> 148. Compare the function definitions from this section
|
|
(<span class="RktSym">sum</span>, <span class="RktSym">how-many</span>, <span class="RktSym">all-true</span>, <span class="RktSym">one-true</span>) with
|
|
the corresponding function definitions from the preceding sections. Is it
|
|
better to work with data definitions that accommodate empty lists as opposed to
|
|
definitions for non-empty lists? Why? Why not? <a href="part_two.html#%28counter._%28exercise._nelist3%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>9.3<tt> </tt><a name="(part._sec~3anats)"></a>Natural Numbers</h4><p><div class="SIntrapara">The BSL programming language supplies many functions that consume lists and a
|
|
few that produce them, too. Among those is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span>, which consumes a
|
|
number <span class="RktSym">n</span> together with some other value <span class="RktSym">v</span> and
|
|
produces a list that contains <span class="RktSym">v</span> <span style="font-style: italic">n</span> times. Here are some
|
|
examples:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(cons "hello" (cons "hello" '()))</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(cons #true (cons #true (cons #true '())))</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">17</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">'()</span></p></td></tr></table></blockquote></div><div class="SIntrapara">In short, even though this function consumes atomic data, it produces
|
|
arbitrarily large pieces of data. Your question should be how this is possible.</div></p><p><div class="SIntrapara">Our answer is that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span>’s input isn’t just a number, it is a
|
|
special kind of number. In kindergarten you called these numbers “counting
|
|
numbers”, that is, these numbers are used to count objects. In computer science,
|
|
these numbers are dubbed <span style="font-style: italic">natural numbers</span>. Unlike regular numbers,
|
|
natural numbers come with a data definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._n)"></a><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"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">0</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> represents the counting numbers</span></td></tr></table></blockquote></div><div class="SIntrapara">The first clause says that <span class="RktVal">0</span> is a natural number; it is
|
|
used to say that there is no object to be counted. The second clause tells
|
|
you that if <span style="font-style: italic">n</span> is a natural number, then <span style="font-style: italic">n+</span>1<span style="font-style: italic"></span> is one too,
|
|
because <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span> is a function that adds <span class="RktVal">1</span> to whatever
|
|
number it is given. We could write this second clause as <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%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">1</span><span class="RktPn">)</span>,
|
|
but the use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span> is supposed to signal that this addition is
|
|
special.</div></p><p>What is special about this use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span> is that it acts more like a
|
|
constructor from some structure-type definition than a regular function. For
|
|
that reason, BSL also comes with the function <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span>, which is the
|
|
“selector” corresponding to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span>. Given any natural number <span style="font-style: italic">m</span>
|
|
not equal to <span class="RktVal">0</span>, you can use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span> to find out the number that
|
|
went into the construction of <span style="font-style: italic">m</span>. Put differently, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._add1%29%29" class="RktValLink" data-pltdoc="x">add1</a></span> is like
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span> is like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>.</p><p>At this point you may wonder what the predicates are that distinguish <span class="RktVal">0</span>
|
|
from those natural numbers that are not <span class="RktVal">0</span>. There are two, just as for
|
|
lists: <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span>, which determines whether some given number is
|
|
<span class="RktVal">0</span>, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._positive~3f%29%29" class="RktValLink" data-pltdoc="x">positive?</a></span>, which determines whether some number is
|
|
larger than <span class="RktVal">0</span>.</p><p><div class="SIntrapara">Now you are in a position to design functions on natural numbers, such as
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-list%29%29" class="RktValLink" data-pltdoc="x">make-list</a></span>, yourself. The data definition is already available, so
|
|
let’s add the header material: <a name="(idx._(gentag._237))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a list of </span><span class="RktSym">n</span><span class="RktCmt"> copies of </span><span class="RktSym">s</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Developing the template is the next step. The questions for the template suggest
|
|
that <span class="RktSym">copier</span>’s body is a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression with two clauses: one
|
|
for <span class="RktVal">0</span> and one for positive numbers. Furthermore, <span class="RktVal">0</span> is
|
|
considered atomic and positive numbers are considered structured values,
|
|
meaning the template needs a selector expression in the second clause. Last but
|
|
not least, the data definition for <a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a> is self-referential in the second
|
|
clause. Hence the template needs a recursive application to the corresponding
|
|
selector expression in the second clause:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._positive~3f%29%29" class="RktValLink" data-pltdoc="x">positive?</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></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"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a list of </span><span class="RktSym">n</span><span class="RktCmt"> copies of </span><span class="RktSym">s</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._positive~3f%29%29" class="RktValLink" data-pltdoc="x">positive?</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3acopier))" x-target-lift="Figure"></a>Figure 59: </span>Creating a list of copies</span></p></blockquote><p><div class="SIntrapara"><a href="part_two.html#%28counter._%28figure._fig~3acopier%29%29" data-pltdoc="x">Figure <span class="FigureRef">59</span></a> contains a complete definition of the <span class="RktSym">copier</span>
|
|
function, as obtained from its template. Let’s reconstruct this step
|
|
carefully. As always, we start with the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause that has no
|
|
recursive calls. Here the condition tells us that the (important) input is
|
|
<span class="RktVal">0</span>, and that means the function must produce a list with
|
|
<span class="RktVal">0</span> items, that is, <span style="font-weight: bold">none</span>. Of course, working through the
|
|
second example has already clarified this case. Next we turn to the other
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause and remind ourselves what its expressions compute:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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> extracts the natural number that went into the
|
|
construction of <span class="RktSym">n</span>, which we know is larger than <span class="RktVal">0</span>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym">copier</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span> produces a list of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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>
|
|
strings <span class="RktSym">s</span> according to the purpose statement of <span class="RktSym">copier</span>.</p></li></ol></div><div class="SIntrapara">But the function is given <span class="RktSym">n</span> and must therefore produce a list
|
|
with <span class="RktSym">n</span> strings <span class="RktSym">s</span>. Given a list with one too few strings,
|
|
it is easy to see that the function must simply <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> one
|
|
<span class="RktSym">s</span> onto the result of <span class="RktPn">(</span><span class="RktSym">copier</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span>. And that is
|
|
precisely what the second clause specifies.</div></p><p>At this point, you should run the tests to ensure that this function works
|
|
at least for the two worked examples. In addition, you may wish to use the
|
|
function on some additional inputs.</p><p><a name="(counter._(exercise._n1))"></a><span style="font-weight: bold">Exercise</span> 149. Does <span class="RktSym">copier</span> function properly when you apply it to
|
|
a natural number and a Boolean or an image? Or do you have to design another
|
|
function? Read <a href="part_three.html" data-pltdoc="x">Abstraction</a> for an answer.</p><p><div class="SIntrapara">An alternative definition of <span class="RktSym">copier</span> might use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span>: <a name="(idx._(gentag._238))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier.v2</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">copier.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">How do <span class="RktSym">copier</span> and <span class="RktSym">copier.v2</span> behave when you apply them to
|
|
<span class="RktVal">0.1</span> and <span class="RktVal">"x"</span>? Explain. Use DrRacket’s stepper to confirm
|
|
your explanation. <a href="part_two.html#%28counter._%28exercise._n1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._n2))"></a><span style="font-weight: bold">Exercise</span> 150. Design the function <span class="RktSym">add-to-pi</span>. It consumes a
|
|
natural number <span class="RktSym">n</span> and adds it to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span> <span style="font-weight: bold">without</span> using
|
|
the primitive <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span> operation. Here is a start: <a name="(idx._(gentag._239))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktPn">)</span><span class="RktCmt"> without using </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-within%29%29" class="RktStxLink" data-pltdoc="x">check-within</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-to-pi</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0.001</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-to-pi</span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._pi%29%29" class="RktValLink" data-pltdoc="x">pi</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Once you have a complete definition, generalize the function to
|
|
<span class="RktSym">add</span>, which adds a natural number <span class="RktSym">n</span> to some arbitrary
|
|
number <span class="RktSym">x</span> without using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span>. Why does the skeleton use
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-within%29%29" class="RktStxLink" data-pltdoc="x">check-within</a></span>? <a href="part_two.html#%28counter._%28exercise._n2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._n3))"></a><span style="font-weight: bold">Exercise</span> 151. Design the function <span class="RktSym">multiply</span>. It consumes a
|
|
natural number <span class="RktSym">n</span> and multiplies it with a number <span class="RktSym">x</span>
|
|
without using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span>.</p><p>Use DrRacket’s stepper to evaluate <span class="RktPn">(</span><span class="RktSym">multiply</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span> for any <span class="RktSym">x</span>
|
|
you like. How does <span class="RktSym">multiply</span> relate to what you know from grade
|
|
school? <a href="part_two.html#%28counter._%28exercise._n3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3acol-row))"></a><span style="font-weight: bold">Exercise</span> 152. Design two functions: <span class="RktSym">col</span> and <span class="RktSym">row</span>.</p><p>The function <span class="RktSym">col</span> consumes a natural number <span class="RktSym">n</span> and an image
|
|
<span class="RktSym">img</span>. It produces a column—<wbr></wbr>a vertical arrangement—<wbr></wbr>of <span class="RktSym">n</span>
|
|
copies of <span class="RktSym">img</span>.</p><p>The function <span class="RktSym">row</span> consumes a natural number <span class="RktSym">n</span> and an image
|
|
<span class="RktSym">img</span>. It produces a row—<wbr></wbr>a horizontal arrangement—<wbr></wbr>of <span class="RktSym">n</span>
|
|
copies of <span class="RktSym">img</span>. <a href="part_two.html#%28counter._%28exercise._ex~3acol-row%29%29" class="ex-end" data-pltdoc="x"></a></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_96.png" alt="image" width="106.0" height="206.0"/><span class="hspace"> </span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_97.png" alt="image" width="106.0" height="206.0"/><span class="hspace"> </span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_98.png" alt="image" width="106.0" height="206.0"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3arandom1))" x-target-lift="Figure"></a>Figure 60: </span>Random attacks</span></p></blockquote><p><a name="(counter._(exercise._ex~3arandom1))"></a><span style="font-weight: bold">Exercise</span> 153. The goal of this exercise is to visualize the
|
|
result of a 1968-style European student riot. Here is the rough idea. A
|
|
small group of students meets to make paint-filled balloons, enters some
|
|
lecture hall, and randomly throws the balloons at the attendees. Your
|
|
program displays how the balloons color the seats in the lecture hall.</p><p>Use the two functions from <a href="part_two.html#%28counter._%28exercise._ex~3acol-row%29%29" data-pltdoc="x">exercise 152</a> to create a rectangle of <span class="stt">COLUMNS</span> by
|
|
<span class="stt">ROWS</span> squares, each of which has size 10 by 10. Place it in an
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span> of the same size. This image is your lecture hall.</p><p>Design <span class="RktSym">add-balloons</span>. The function consumes a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>
|
|
whose coordinates fit into the dimensions of the lecture hall. It produces
|
|
an image of the lecture hall with red dots added as specified by the
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s.</p><p><a href="part_two.html#%28counter._%28figure._fig~3aex~3arandom1%29%29" data-pltdoc="x">Figure <span class="FigureRef">60</span></a> shows the output of <span style="font-weight: bold">our</span> solution
|
|
for 10 <span class="stt">COLUMNS</span> columns and 20 <span class="stt">ROWS</span> when given some list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. The
|
|
left-most is the clean lecture hall, the second one is after two
|
|
balloons have hit, and the last one is a highly unlikely distribution
|
|
of 10 hits. Where is the 10th? <a href="part_two.html#%28counter._%28exercise._ex~3arandom1%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>9.4<tt> </tt><a name="(part._rd._sec~3ard)"></a>Russian Dolls</h4><p><div class="SIntrapara">Wikipedia defines a Russian doll as “a set of dolls of decreasing sizes
|
|
placed one inside the other” and illustrates it with this picture:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="russian-doll-from-wikipedia.png" alt="" width="192" height="104"/></p></blockquote></div><div class="SIntrapara">In this picture, the dolls are taken apart so that the viewer can see them
|
|
all.</div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>The problem may strike you as abstract or even absurd;
|
|
it isn’t clear why you would want to represent Russian dolls or
|
|
what you would do with such a representation. Just play along for now.</p></blockquote></blockquote></blockquote><p>Now consider the problem of representing such Russian dolls with BSL data.
|
|
With a little bit of imagination, it is easy to see that an artist can
|
|
create a nest of Russian dolls that consists of an arbitrary number of
|
|
dolls. After all, it is always possible to wrap another layer around some
|
|
given Russian doll. Then again, you also know that deep inside there is a
|
|
solid doll without anything inside.</p><p>For each layer of a Russian doll, we could care about many different
|
|
things: its size, though it is related to the nesting level; its color;
|
|
the image that is painted on the surface; and so on. Here we just pick
|
|
one, namely the color of the doll, which we represent with a string.
|
|
Given that, we know that each layer of the Russian doll has two
|
|
properties: its color and the doll that is inside. To represent pieces of
|
|
information with two properties, we always define a structure type:
|
|
<a name="(idx._rd._(gentag._240._rd))"></a></p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">layer</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._color%29%29" class="RktValLink" data-pltdoc="x">color</a></span><span class="hspace"> </span><span class="RktSym">doll</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">And then we add a data definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._rd._rd)"></a><span style="font-style: italic">RD</span><span class="RktCmt"> (short for </span><span style="font-style: italic">Russian doll</span><span class="RktCmt">) is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Naturally, the first clause of this data definition represents the
|
|
innermost doll, or, to be precise, its color. The second clause is for
|
|
adding a layer around some given Russian doll. We represent this with an
|
|
instance of <span class="RktSym">layer</span>, which obviously contains the color
|
|
of the doll and one other field: the doll that is nested immediately
|
|
inside of this doll.</div></p><p><div class="SIntrapara">Take a look at this doll:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_99.png" alt="image" width="87.0" height="127.5"/></p></blockquote></div><div class="SIntrapara">It consists of three dolls. The red one is the innermost one, the green one
|
|
sits in the middle, and the yellow is the current outermost wrapper. To
|
|
represent this doll with an element of <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a>, you start on either
|
|
end. We proceed from the inside out. The red doll is easy to represent as
|
|
an <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a>. Since nothing is inside and since it is red, the string
|
|
<span class="RktVal">"red"</span> will do fine. For the second layer, we use
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">which says that a green (hollow) doll contains a red doll. Finally,
|
|
to get the outside we just wrap another layer around this last doll:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"yellow"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">This process should give you a good idea of how to go from any set of colored
|
|
Russian dolls to a data representation. But keep in mind that a programmer
|
|
must also be able to do the converse, that is, go from a piece of data to
|
|
concrete information. In this spirit, draw a schematic Russian doll for
|
|
the following element of <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"pink"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"black"</span><span class="hspace"> </span><span class="RktVal">"white"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">You might even try this in BSL.</div></p><p><div class="SIntrapara">Now that we have a data definition and understand how to represent actual
|
|
dolls and how to interpret elements of <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a> as dolls, we are ready to
|
|
design functions that consume <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a>s. Specifically, let’s design the
|
|
function that counts how many dolls a Russian doll set contains. This
|
|
sentence is a fine purpose statement and determines the signature, too:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">how many dolls are part of </span><span class="RktSym">an-rd</span><span class="RktCmt"> </span></td></tr></table></blockquote></div><div class="SIntrapara">As for data examples, let’s start with <span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="stt"> </span><span class="RktVal">"yellow"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="stt"> </span><span class="RktVal">"green"</span><span class="stt"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span>. The image above tells us that <span class="RktVal">3</span> is
|
|
the expected answer because there are three dolls: the red one, the green
|
|
one, and the yellow one. Just working through this one example also tells
|
|
us that when the input is a representation of this doll
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_100.png" alt="image" width="33.0" height="46.5"/></p></blockquote></div><div class="SIntrapara">then the answer is <span class="RktVal">1</span>.</div></p><p><div class="SIntrapara">Step four demands the development of a template. Using the standard
|
|
questions for this step produces this template: <a name="(idx._rd._(gentag._241._rd))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">how many dolls are a part of </span><span class="RktSym">an-rd</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">layer?</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">layer-color</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 number of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses is determined by the number of clauses
|
|
in the definition of <a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a>. Each of the clauses specifically spells
|
|
out what kind of data it is about, and that tells us to
|
|
use the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span> and <span class="RktSym">layer?</span> predicates. While strings aren’t compound data,
|
|
instances of <span class="RktSym">layer</span> contain two values. If the function needs
|
|
these values, it uses the selector expressions <span class="RktPn">(</span><span class="RktSym">layer-color</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span>
|
|
and <span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span>. Finally, the second clause of the data
|
|
definition contains a self-reference from the <span style="font-style: italic">doll</span> field of the
|
|
<span class="RktSym">layer</span> structure to the definition itself. Hence we need a
|
|
recursive function call for the second selector expression.</div></p><p><div class="SIntrapara">The <a name="(idx._rd._(gentag._242._rd))"></a>examples and the <a name="(idx._rd._(gentag._243._rd))"></a>template almost dictate the function definition. For
|
|
the non-recursive <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause, the answer is obviously
|
|
<span class="RktVal">1</span>. For the recursive clause, the template expressions compute the
|
|
following results:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym">layer-color</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span> extracts the string that describes the
|
|
color of the current layer;</p></li><li><p><span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span> extracts the doll contained within the
|
|
current layer; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">depth</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="RktPn">)</span> determines how many dolls are
|
|
part of <span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span>, according to the purpose statement
|
|
of <span class="RktSym">depth</span>.</p></li></ul></div><div class="SIntrapara">This last number is almost the desired answer but not quite because the
|
|
difference between <span class="RktSym">an-rd</span> and <span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span> is one
|
|
layer, meaning one extra doll. Put differently, the function must add
|
|
<span class="RktVal">1</span> to the recursive result to obtain the actual answer:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">how many dolls are a part of </span><span class="RktSym">an-rd</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">layer-doll</span><span class="hspace"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Note how the function definition does not use <span class="RktPn">(</span><span class="RktSym">layer-color</span><span class="stt"> </span><span class="RktSym">an-rd</span><span class="RktPn">)</span>
|
|
in the second clause. Once again, we see that the template is an
|
|
organization schema for everything we know about the data definition, but
|
|
we may not need all of these pieces for the actual definition.</div></p><p><div class="SIntrapara">Let’s finally translate the examples into 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">depth</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"yellow"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-layer</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you run these in DrRacket, you will see that their evaluation touches all
|
|
pieces of the definition of <span class="RktSym">depth</span>.</div></p><p><div class="SIntrapara"><a name="(counter._rd._(exercise._rd1))"></a><span style="font-weight: bold">Exercise</span> 154. Design the function <span class="RktSym">colors</span>. It consumes a Russian
|
|
doll and produces a string of all colors, separated by a comma and a
|
|
space. Thus our example should produce
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">"yellow, green, red"</span></p></blockquote></div><div class="SIntrapara"><a href="part_two.html#%28counter._rd._%28exercise._rd1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._rd._(exercise._rd2))"></a><span style="font-weight: bold">Exercise</span> 155. Design the function <span class="RktSym">inner</span>, which consumes an
|
|
<a href="part_two.html#%28tech._rd._rd%29" class="techoutside" data-pltdoc="x"><span class="techinside">RD</span></a> and produces the (color of the) innermost doll. Use DrRacket’s stepper
|
|
to evaluate <span class="RktPn">(</span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktSym">rd</span><span class="RktPn">)</span> for your favorite <span class="RktSym">rd</span>. <a href="part_two.html#%28counter._rd._%28exercise._rd2%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>9.5<tt> </tt><a name="(part._sec~3alist-world)"></a>Lists and World</h4><p><div class="SIntrapara">With lists and self-referential data definitions in general, you can design
|
|
and run many more interesting world programs than with finite data. Just
|
|
imagine you can now create a version of the space invader program from
|
|
<a href="part_one.html#%28part._ch~3amix%29" data-pltdoc="x">Itemizations and Structures</a> that allows the player to fire as many shots from the tank
|
|
as desired. Let’s start with a simplistic version of this
|
|
problem:<span class="refelem"><span class="refcolumn"><span class="refcontent">If you haven’t designed a world program in a while,
|
|
reread <a href="part_one.html#%28part._.D.K._sec~3adesign-world%29" data-pltdoc="x">Designing World Programs</a>.</span></span></span>
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a world program that simulates firing shots. Every
|
|
time the “player” hits the space bar, the program adds a shot to the
|
|
bottom of the canvas. These shots rise vertically at the rate of one pixel
|
|
per tick.</p></blockquote></div></p><p><div class="SIntrapara">Designing a world program starts with a separation of information into
|
|
constants and elements of the ever-changing state of the world. For the
|
|
former we introduce physical and graphical constants; for the latter we
|
|
need to develop a <a name="(idx._(gentag._244))"></a>data representation for world states. While the sample
|
|
problem is relatively vague about the specifics, it clearly assumes a
|
|
rectangular scenery with shots painted along a vertical line. Obviously
|
|
the locations of the shots change with every clock tick, but the size of
|
|
the scenery and x-coordinate of the line of shots remain the same:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">80</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">distances in terms of pixels </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktVal">100</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">XSHOTS</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">graphical constants </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktSym">HEIGHT</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">SHOT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._triangle%29%29" class="RktValLink" data-pltdoc="x">triangle</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Nothing in the problem statement demands these particular choices, but as
|
|
long as they are easy to change—<wbr></wbr>meaning changing by editing a single
|
|
definition—<wbr></wbr>we have achieved our goal.</div></p><p><div class="SIntrapara">As for those aspects of the “world” that change, the problem statement
|
|
mentions two. First, hitting the space bar adds a shot. Second, all the
|
|
shots move straight up by one pixel per clock tick. Given that we cannot
|
|
predict how many shots the player will “fire,” we use a list to
|
|
represent them:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._shot)"></a><span style="font-style: italic">List-of-shots</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._shot%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shot</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list._of._shot%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-shots</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> the collection of shots fired </span></td></tr></table></blockquote></div><div class="SIntrapara">The one remaining question is how to represent each individual shot. We
|
|
already know that all of them have the same x-coordinate and that
|
|
this coordinate stays the same throughout. Furthermore, all shots look
|
|
alike. Hence, their y-coordinates are the only property in which
|
|
they differ from each other. It therefore suffices to represent each shot
|
|
as a number:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._shot)"></a><span style="font-style: italic">Shot</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">.</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> represents the shot</span><span class="RktCmt">'</span><span class="RktCmt">s y-coordinate </span></td></tr></table></blockquote></div><div class="SIntrapara">We could restrict the representation of shots to the interval of numbers
|
|
below <span class="RktSym">HEIGHT</span> because we know that all shots are launched from the
|
|
bottom of the canvas and that they then move up, meaning their
|
|
y-coordinate continuously decreases.</div></p><p><div class="SIntrapara">You can also use a data definition like this to represent this
|
|
world:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._shotworld)"></a><span style="font-style: italic">ShotWorld</span><span class="RktCmt"> is </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt">. </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> each number on such a list</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">represents the y-coordinate of a shot </span></td></tr></table></blockquote></div><div class="SIntrapara">After all, the above two definitions describe all list of numbers; we
|
|
already have a definition for lists of numbers, and the name
|
|
<a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a> tells everyone what this class of data is about.</div></p><p><div class="SIntrapara">Once you have defined constants and developed a data representation for
|
|
the states of the world, the key task is to pick which event handlers you
|
|
wish to employ and to adapt their signatures to the given problem. The running
|
|
example mentions clock ticks and the space bar, all of which translates
|
|
into a wish list of three functions:
|
|
</div><div class="SIntrapara"><ul><li><p><div class="SIntrapara">the function that turns a world state into an image: <a name="(idx._(gentag._245))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds the image of a shot for each</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktMeta"></span><span class="RktCmt"> on </span><span class="RktSym">w</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">at (</span><span class="RktSym">MID</span><span class="RktCmt">,</span><span class="RktSym">y</span><span class="RktCmt">) to the background image </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">because the problem demands a visual rendering;</div></p></li><li><p><div class="SIntrapara">one for dealing with tick events: <a name="(idx._(gentag._246))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">moves each shot on </span><span class="RktSym">w</span><span class="RktCmt"> up by one pixel </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tock</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p></li><li><p><div class="SIntrapara">and one function for dealing with key events: <a name="(idx._(gentag._247))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds a shot to the world </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">if the player presses the space bar</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keyh</span><span class="hspace"> </span><span class="RktSym">w</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p></li></ul></div><div class="SIntrapara">Don’t forget that in addition to the initial wish list, you also need to
|
|
define a <span class="RktSym">main</span> function that actually sets up the world and
|
|
installs the handlers. <a href="part_two.html#%28counter._%28figure._fig~3ashots%29%29" data-pltdoc="x">Figure <span class="FigureRef">61</span></a> includes this one function that
|
|
is not designed but defined as a modification of standard schema.</div></p><p><div class="SIntrapara">Let’s start with the design of <span class="RktSym">to-image</span>. We have its signature,
|
|
purpose statement, and header, so we need examples next. Since the data
|
|
definition has two clauses, there should be at least two examples:
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> and a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed list, say, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">9</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>. The expected result for <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is obviously
|
|
<span class="RktSym">BACKGROUND</span>; if there is a y-coordinate, though, the
|
|
function must place the image of a shot at <span class="RktSym">MID</span> and the specified
|
|
coordinate:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">SHOT</span><span class="hspace"> </span><span class="RktSym">XSHOTS</span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Before you read on, work through an example that applies <span class="RktSym">to-image</span>
|
|
to a list of two <a href="part_two.html#%28tech._shot%29" class="techoutside" data-pltdoc="x"><span class="techinside">Shot</span></a>s. Doing so helps understand
|
|
<span style="font-weight: bold">how</span> the function works.</div></p><p><div class="SIntrapara">The fourth step is about translating the data definition into a template:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 template for data definitions for lists is so familiar now that it
|
|
doesn’t need much explanation. If you have any doubts, read
|
|
over the questions in <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure <span class="FigureRef">52</span></a> and design the template on your
|
|
own.</div></p><p><div class="SIntrapara">From here it is straightforward to define the function. The key is to
|
|
combine the examples with the template and to answer the questions from
|
|
<a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">figure <span class="FigureRef">53</span></a>. Following those, you start with the base case
|
|
of an empty list of shots, and, from the examples, you know that the
|
|
expected answer is <span class="RktSym">BACKGROUND</span>. Next you formulate what the
|
|
template expressions in the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> compute:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span> extracts the first coordinate from the list;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span> is the rest of the coordinates; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span> adds each shot on <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span> to
|
|
the background image, according to the purpose statement of <span class="RktSym">to-image</span>.</p></li></ul></div><div class="SIntrapara">In other words, <span class="RktPn">(</span><span class="RktSym">to-image</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span> renders the rest of the list
|
|
as an image and thus performs almost all the work. What is missing is the
|
|
first shot, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span>. If you now apply the purpose
|
|
statement to these two expressions, you get the desired expression for the
|
|
second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">SHOT</span><span class="hspace"> </span><span class="RktSym">XSHOTS</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The added icon is the standard image for a shot; the two coordinates are
|
|
spelled out in the purpose statement; and the last argument to
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span> is the image constructed from the rest of the list.</div></p><p><a href="part_two.html#%28counter._%28figure._fig~3ashots%29%29" data-pltdoc="x">Figure <span class="FigureRef">61</span></a> displays the complete function definition for
|
|
<span class="RktSym">to-image</span> and indeed the rest of the program, too. The design of
|
|
<span class="RktSym">tock</span> is just like the design of <span class="RktSym">to-image</span>, and you should
|
|
work through it for yourself. The signature of the <span class="RktSym">keyh</span> handler,
|
|
though, poses one interesting question. It specifies that the handler
|
|
consumes two inputs with nontrivial data definitions. On the one hand, the
|
|
<a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a> is a self-referential data definition. On the other hand,
|
|
the definition for <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a>s is a large enumeration. For now, we
|
|
have you “guess” which of the two arguments should drive the development
|
|
of the template; later we will study such cases in depth.</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"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">main</span><span class="hspace"> </span><span class="RktSym">w0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym">w0</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-tick%29%29" class="RktStxLink" data-pltdoc="x">on-tick</a></span><span class="hspace"> </span><span class="RktSym">tock</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">keyh</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">to-image</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">moves each shot up by one pixel </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tock</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._sub1%29%29" class="RktValLink" data-pltdoc="x">sub1</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">tock</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds a shot to the world if the space bar is hit </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keyh</span><span class="hspace"> </span><span class="RktSym">w</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">" "</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._shotworld%29" class="techoutside" data-pltdoc="x"><span class="techinside">ShotWorld</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds each shot </span><span class="RktSym">y</span><span class="RktCmt"> on </span><span class="RktSym">w</span><span class="RktMeta"></span><span class="RktCmt"> at (</span><span class="RktSym">XSHOTS</span><span class="RktCmt">,</span><span class="RktSym">y</span><span class="RktCmt">} to </span><span class="RktSym">BACKGROUND</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">BACKGROUND</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span><span class="hspace"> </span><span class="RktSym">SHOT</span><span class="hspace"> </span><span class="RktSym">XSHOTS</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">to-image</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3ashots))" x-target-lift="Figure"></a>Figure 61: </span>A list-based world program</span></p></blockquote><p><div class="SIntrapara">As far as a world program is concerned, a key handler such as <span class="RktSym">keyh</span>
|
|
is about the key event that it consumes. Hence, we consider it the main
|
|
argument and use its data definition to derive the template. Specifically,
|
|
following the data definition for <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a> from <a href="part_one.html#%28part._sec~3aenums%29" data-pltdoc="x">Enumerations</a>, it
|
|
dictates that the function needs a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression with numerous
|
|
clauses 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">keyh</span><span class="hspace"> </span><span class="RktSym">w</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">"left"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">"right"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">" "</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">ke</span><span class="hspace"> </span><span class="RktVal">"z"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Of course, just like for functions that consume all possible BSL values, a
|
|
key handler usually does not need to inspect all possible cases. For our
|
|
running problem, you specifically know that the key handler reacts only
|
|
to the space bar and all others are ignored. So it is natural to collapse
|
|
all of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses into an <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span> clause except for
|
|
the clause for <span class="RktVal">" "</span>.</div></p><p><a name="(counter._(exercise._shots1))"></a><span style="font-weight: bold">Exercise</span> 156. Equip the program in <a href="part_two.html#%28counter._%28figure._fig~3ashots%29%29" data-pltdoc="x">figure <span class="FigureRef">61</span></a> with tests and
|
|
make sure it passes those. Explain what <span class="RktSym">main</span> does. Then run the
|
|
program via <span class="RktSym">main</span>. <a href="part_two.html#%28counter._%28exercise._shots1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._shots2))"></a><span style="font-weight: bold">Exercise</span> 157. Experiment to determine whether the arbitrary decisions concerning constants
|
|
are easy to change. For example, determine whether changing a single
|
|
constant definition achieves the desired outcome:
|
|
</div><div class="SIntrapara"><ul><li><p>change the height of the canvas to 220 pixels;</p></li><li><p>change the width of the canvas to 30 pixels;</p></li><li><p>change the <span style="font-style: italic">x</span> location of the line of shots to “somewhere to
|
|
the left of the middle”;</p></li><li><p>change the background to a green rectangle; and</p></li><li><p>change the rendering of shots to a red elongated rectangle.</p></li></ul></div><div class="SIntrapara">Also check whether it is possible to double the size of the shot without
|
|
changing anything else or to change its color to black. <a href="part_two.html#%28counter._%28exercise._shots2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._shots3))"></a><span style="font-weight: bold">Exercise</span> 158. If you run <span class="RktSym">main</span>, press the space bar (fire a
|
|
shot), and wait for a goodly amount of time, the shot disappears from the
|
|
canvas. When you shut down the world canvas, however, the result is a
|
|
world that still contains this invisible shot.</p><p>Design an alternative <span class="RktSym">tock</span> function that doesn’t just move shots
|
|
one pixel per clock tick but also eliminates those whose coordinates
|
|
place them above the canvas. <span style="font-weight: bold">Hint</span> You may wish to consider the design of
|
|
an auxiliary function for the recursive <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause. <a href="part_two.html#%28counter._%28exercise._shots3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._riot2))"></a><span style="font-weight: bold">Exercise</span> 159. Turn the solution of <a href="part_two.html#%28counter._%28exercise._ex~3arandom1%29%29" data-pltdoc="x">exercise 153</a> into a world
|
|
program. Its main function, dubbed <span class="RktSym">riot</span>, consumes how many
|
|
balloons the students want to throw; its visualization shows one balloon
|
|
dropping after another at a rate of one per second. The function produces
|
|
the list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s where the balloons hit.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hints</span> (1) Here is one possible 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">pair</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">balloon#</span><span class="hspace"> </span><span class="RktSym">lob</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._pair)"></a><span style="font-style: italic">Pair</span><span class="RktCmt"> is a structure </span><span class="RktPn">(</span><span class="RktSym">make-pair</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="stt"> </span><a href="part_two.html#%28tech._list._of._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-posns</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._list._of._posn)"></a><span style="font-style: italic">List-of-posns</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list._of._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-posns</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-pair</span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym">lob</span><span class="RktPn">)</span><span class="RktCmt"> means </span><span class="RktSym">n</span><span class="RktCmt"> balloons </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">must yet be thrown and added to </span><span class="RktSym">lob</span></td></tr></table></blockquote></div></p><p>(2) 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 is really just an expression. It is
|
|
legitimate to nest it within another expression.</p><p>(3) Recall that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span> creates random numbers. <a href="part_two.html#%28counter._%28exercise._riot2%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>9.6<tt> </tt><a name="(part._sec~3alist-set)"></a>A Note on Lists and Sets</h4><p>This book relies on your intuitive understanding of <span style="font-style: italic">sets</span> as
|
|
collections of BSL values. <a href="part_one.html#%28part._data-uni._sec~3adata-uni%29" data-pltdoc="x">The Universe of Data</a> specifically says that a data definition
|
|
introduces a name for a set of BSL values. There is one question that
|
|
this book consistently asks about sets, and it is whether some element is
|
|
in some given set. For example, <span class="RktVal">4</span> is in <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>, while
|
|
<span class="RktVal">"four"</span> is not. The book also shows how to use a data definition to
|
|
check whether some value is a member of some named set and how to use some
|
|
of the data definitions to generate sample elements of sets, but these two
|
|
procedures are about data definitions, not sets per se.</p><p>At the same time, lists represent collections of values.
|
|
Hence you might be wondering what the difference between a list and a set
|
|
is or whether this is a needless distinction. If so, this section is for you.</p><p>Right now the primary difference between sets and lists is that the former
|
|
is a concept we use to discuss steps in the design of code and the latter
|
|
is one of many forms of data in BSL, our chosen programming
|
|
language. The two ideas live at rather different levels in our
|
|
conversations. However, given that a data definition introduces a data
|
|
representation of actual information inside of BSL and given that sets
|
|
are collections of information, you may now ask yourself how sets are
|
|
represented inside of BSL as data.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Most full-fledged languages directly support data
|
|
representations of both lists and sets.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">While lists have a special status in BSL, sets don’t, but at the same
|
|
time sets somewhat resemble lists. The key difference is the kind of
|
|
functions a program normally uses with either form of data. BSL provides
|
|
several basic constants and functions for lists—<wbr></wbr>say, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty%29%29" class="RktValLink" data-pltdoc="x">empty</a></span>,
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>—<wbr></wbr>and some functions that you could define yourself—<wbr></wbr>for
|
|
example, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._remove%29%29" class="RktValLink" data-pltdoc="x">remove</a></span>,
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span>, and so on. Here is an example of a function you can
|
|
define but does not come with BSL <a name="(idx._(gentag._248))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-string</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines how often </span><span class="RktSym">s</span><span class="RktCmt"> occurs in </span><span class="RktSym">los</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">count</span><span class="hspace"> </span><span class="RktSym">los</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Finish the design of this function.</div></p><p>Let’s proceed in a straightforward and possibly naive manner and say sets are
|
|
basically lists. And, to simplify further, let’s focus on lists of numbers
|
|
in this section. If we now accept that it merely matters whether a number
|
|
is a part of a set or not, it is almost immediately clear that we can use
|
|
lists in <span style="font-weight: bold">two</span> different ways to represent sets.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._son..l)"></a><span style="font-style: italic">Son.L</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty%29%29" class="RktValLink" data-pltdoc="x">empty</a></span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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><a href="part_two.html#%28tech._son..l%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.L</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a name="(tech._son)"></a><span style="font-style: italic">Son</span><span class="RktCmt"> is used when it </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">applies to </span><a href="part_two.html#%28tech._son..l%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.L</span></a><span class="RktCmt"> and </span><a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._son..r)"></a><span style="font-style: italic">Son.R</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty%29%29" class="RktValLink" data-pltdoc="x">empty</a></span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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><a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">Constraint</span><span class="RktCmt"> If </span><span class="RktSym">s</span><span class="RktCmt"> is a </span><a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a><span class="RktCmt">, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">no number occurs twice in </span><span class="RktSym">s</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asets-vs-lists))" x-target-lift="Figure"></a>Figure 62: </span>Two data representations for sets</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3asets-vs-lists%29%29" data-pltdoc="x">Figure <span class="FigureRef">62</span></a> displays the two data definitions. Both
|
|
basically say that a set is represented as a list of numbers. The
|
|
difference is that the definition on the right comes with the constraint
|
|
that no number may occur more than once on the list. After all, the key
|
|
question we ask about a set is whether some number is in the set or not,
|
|
and whether it is in a set once, twice, or three times makes no difference.</p><p><div class="SIntrapara">Regardless of which definition you choose, you can already define two
|
|
important notions: <a name="(idx._(gentag._249))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._son%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">es</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._son%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">is </span><span class="RktSym">x</span><span class="RktCmt"> in </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">in?</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first one is the <span style="font-weight: bold">empty set</span>, which in both cases is represented
|
|
by the empty list. The second one is a membership test.</div></p><p><div class="SIntrapara">One way to build larger sets is to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and the above
|
|
definitions. Say we wish to build a representation of the set that contains
|
|
<span class="RktVal">1</span>, <span class="RktVal">2</span>, and <span class="RktVal">3</span>. Here is one such representation:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">And it works for both data representations. But, 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">really not a representation of the same set? Or how about
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The answer has to be affirmative as long as the primary concern is whether
|
|
a number is in a set or not. Still, while the order of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> cannot
|
|
matter, the constraint in the right-hand data definition rules out the last
|
|
list as a <a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a> because it contains <span class="RktVal">1</span> twice.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._250))"></a>
|
|
<a name="(idx._(gentag._251))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0"><tr><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._son..l%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.L</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._son..l%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.L</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">removes </span><span class="RktSym">x</span><span class="RktCmt"> from </span><span class="RktSym">s</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">s1.L</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-.L</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">s1.L</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">es</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-.L</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._remove-all%29%29" class="RktValLink" data-pltdoc="x">remove-all</a></span></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._son..r%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son.R</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">removes </span><span class="RktSym">x</span><span class="RktCmt"> from </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">s1.R</span></td></tr><tr><td><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-.R</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">s1.R</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">es</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-.R</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="highlighted"><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._remove%29%29" class="RktValLink" data-pltdoc="x">remove</a></span></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asets-vs-lists-ops))" x-target-lift="Figure"></a>Figure 63: </span>Functions for the two data representations of sets</span></p></blockquote></div></p><p><div class="SIntrapara">The difference between the two data definitions shows up when we design
|
|
functions. Say we want a function that removes
|
|
a number from a set. Here is a wish-list entry that applies to both
|
|
representations: <a name="(idx._(gentag._252))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._son%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._son%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">subtracts </span><span class="RktSym">x</span><span class="RktCmt"> from </span><span class="RktSym">s</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The purpose statement uses the word “subtract” because this is what
|
|
logicians and mathematicians use when they work with sets.</div></p><p><div class="SIntrapara"><a href="part_two.html#%28counter._%28figure._fig~3asets-vs-lists-ops%29%29" data-pltdoc="x">Figure <span class="FigureRef">63</span></a> shows the results. The two columns
|
|
differ in two points:
|
|
</div><div class="SIntrapara"><ol><li><p>The test on the left uses a list that contains <span class="RktVal">1</span> twice,
|
|
while the one on the right represents the same set with a single
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>.</p></li><li><p>Because of these differences, the <span class="RktSym">set-</span> on the left must use
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._remove-all%29%29" class="RktValLink" data-pltdoc="x">remove-all</a></span>, while the one on the right gets away with
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._remove%29%29" class="RktValLink" data-pltdoc="x">remove</a></span>.</p></li></ol></div><div class="SIntrapara">Stop! Copy the code into the DrRacket definitions area and make sure the tests
|
|
pass. Then read on and experiment with the code as you do.</div></p><p><div class="SIntrapara">An unappealing aspect of <a href="part_two.html#%28counter._%28figure._fig~3asets-vs-lists-ops%29%29" data-pltdoc="x">figure <span class="FigureRef">63</span></a> is that the
|
|
tests use <span class="RktSym">es</span>, a plain list, as the expected result. This problem
|
|
may seem minor at first glance. Consider the following example, however:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">set-</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">set123</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">where <span class="RktSym">set123</span> represents the set containing <span class="RktVal">1</span>, <span class="RktVal">2</span>,
|
|
and <span class="RktVal">3</span> in one of two ways:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">set123-version1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">set123-version2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Regardless of which representation we choose, <span class="RktPn">(</span><span class="RktSym">set-</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktSym">set123</span><span class="RktPn">)</span>
|
|
evaluates to one of these two lists:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">set23-version1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">set23-version2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">But we cannot predict which of those two <span class="RktSym">set-</span> produces.</div></p><p><div class="SIntrapara">For the simple case of two alternatives, it is possible to use the
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-member-of%29%29" class="RktStxLink" data-pltdoc="x">check-member-of</a></span> testing facility as follows:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-member-of%29%29" class="RktStxLink" data-pltdoc="x">check-member-of</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-.v1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">set123.v1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">set23-version1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">set23-version2</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If the expected set contains three elements, there are six possible
|
|
variations, not including representations with repetitions, which
|
|
the left-hand data definition allows.</div></p><p>Fixing this problem calls for the combination of two ideas. First, recall
|
|
that <span class="RktSym">set-</span> is really about ensuring that the given element does not
|
|
occur in the result. It is an idea that our way of turning the examples
|
|
into tests does not bring across. Second, with BSL’s
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> testing facility, it is possible to state precisely
|
|
this idea. <a name="(idx._(gentag._253))"></a></p><p><div class="SIntrapara"><a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a> briefly mentions <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span>, but, in a nutshell,
|
|
the facility determines whether an expression satisfies a certain property.
|
|
A property is a function from values to <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a>. In our specific
|
|
case, we wish to state that <span class="RktVal">1</span> is not a member of some set:
|
|
<a name="(idx._(gentag._254))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._son%29" class="techoutside" data-pltdoc="x"><span class="techinside">Son</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktVal">#true</span><span class="RktCmt"> if </span><span class="RktVal">1</span><span class="RktCmt"> is not a member of </span><span class="RktSym">s</span><span class="RktCmt">;</span><span class="hspace"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">not-member-1?</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._not%29%29" class="RktValLink" data-pltdoc="x">not</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">in?</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Using <span class="RktSym">not-member-1?</span>, we can formulate the test case as follows: <a name="(idx._(gentag._255))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">set-</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">set123</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">not-member-1?</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">and this variant clearly states what the function is supposed to
|
|
accomplish. Better yet, this formulation simply does not depend on how the
|
|
input or output set is represented.</div></p><p><div class="SIntrapara">In sum, lists and sets are related in that both are about collections of
|
|
values, but they also differ strongly:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;"><p>property</p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p>lists</p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p>sets</p></td></tr><tr><td><p>membership</p></td><td><p><span class="hspace"> </span></p></td><td><p>one among many</p></td><td><p><span class="hspace"> </span></p></td><td><p>critical</p></td></tr><tr><td><p>ordering</p></td><td><p><span class="hspace"> </span></p></td><td><p>critical</p></td><td><p><span class="hspace"> </span></p></td><td><p>irrelevant</p></td></tr><tr><td><p># of occurrences</p></td><td><p><span class="hspace"> </span></p></td><td><p>sensible</p></td><td><p><span class="hspace"> </span></p></td><td><p>irrelevant</p></td></tr><tr><td><p>size</p></td><td><p><span class="hspace"> </span></p></td><td><p>finite but arbitrary</p></td><td><p><span class="hspace"> </span></p></td><td><p>finite or infinite</p></td></tr></table></blockquote></div><div class="SIntrapara">The last row in this table presents a new idea, though an obvious one,
|
|
too. Many of the sets mentioned in this book are infinitely large, for
|
|
example, <a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a>, <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>, and also <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a>. In
|
|
contrast, a list is <span style="font-weight: bold">always</span> finite though it may contain an
|
|
arbitrarily large number of items.</div></p><p>In sum, this section explains the essential differences between sets and
|
|
lists and how to represent finite sets with finite lists in two different
|
|
ways. BSL is not expressive enough to represent infinite sets;
|
|
<a href="part_three.html#%28counter._%28exercise._ex~3ainfinite-set%29%29" data-pltdoc="x">exercise 299</a> introduces a completely different representation
|
|
of sets, a representation that can cope with infinite sets, too. The
|
|
question of how actual programming languages represent sets is beyond the
|
|
scope of this book, however.</p><p><a name="(counter._(exercise._ex~3aset1))"></a><span style="font-weight: bold">Exercise</span> 160. Design the functions <span class="RktSym">set+.L</span> and
|
|
<span class="RktSym">set+.R</span>, which create a set by adding a number <span class="RktSym">x</span> to some
|
|
given set <span class="RktSym">s</span> for the left-hand and right-hand data definition,
|
|
respectively. <a href="part_two.html#%28counter._%28exercise._ex~3aset1%29%29" class="ex-end" data-pltdoc="x"></a></p><h3>10<tt> </tt><a name="(part._ch~3alists2)"></a>More on Lists</h3><p>Lists are a versatile form of data that come with almost all languages
|
|
now. Programmers have used them to build large applications, artificial
|
|
intelligences, distributed systems, and more. This chapter illustrates
|
|
some ideas from this world, including functions that create lists,
|
|
data representations that call for structures inside of lists, and
|
|
representing text files as lists.</p><h4>10.1<tt> </tt><a name="(part._sec~3alist-produce)"></a>Functions that Produce Lists</h4><p><div class="SIntrapara">Here is a function for determining the wage of an hourly employee: <a name="(idx._(gentag._256))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the wage for </span><span class="RktSym">h</span><span class="RktCmt"> hours of work</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It consumes the number of hours worked and produces the wage. A company
|
|
that wishes to use payroll software isn’t interested in this function,
|
|
however. It wants one that computes the wages for all its employees.</div></p><p>Call this new function <span class="RktSym">wage*</span>. Its task is to process all employee
|
|
work hours and to determine the wages due to each of them. For
|
|
simplicity, let’s assume that the input is a list of numbers, each
|
|
representing the number of hours that one employee worked, and that
|
|
the expected result is a list of the weekly wages earned, also represented
|
|
with a list of numbers.</p><p><div class="SIntrapara">Since we already have a data definition for the inputs and outputs, we can
|
|
immediately move to the second design step: <a name="(idx._(gentag._257))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the weekly wages for the weekly hours</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Next you need some examples of inputs and the corresponding outputs. So you
|
|
make up some short lists of numbers that represent weekly hours:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;"><p>given</p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p>expected</p></td></tr><tr><td><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">28</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">336</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">48</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">24</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">In order to compute the output, you determine the weekly wage for each
|
|
number on the given input list. For the first example, there are no
|
|
numbers on the input list so the output is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. Make sure you
|
|
understand why the second and third expected outputs are what you want.</div></p><p>Given that <span class="RktSym">wage*</span> consumes the same kind of data as several other
|
|
functions from <a href="part_two.html#%28part._ch~3alists1%29" data-pltdoc="x">Lists</a> and given that a template depends only on
|
|
the shape of the data definition, you can reuse this template:</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">In case you want to practice the development of templates, use the
|
|
questions from <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure <span class="FigureRef">52</span></a>.</div></p><p>It is now time for the most creative design step. Following the design
|
|
recipe, we consider each <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line of the template in isolation.
|
|
For the non-recursive case, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span> is true, meaning the
|
|
input is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. The examples from above specify the desired
|
|
answer, <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, and so we are done.</p><p><div class="SIntrapara">In the second case, the design questions tell us to state what each
|
|
expression of the template computes:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span> yields the first number on <span class="RktSym">whrs</span>, which
|
|
is the first number of hours worked;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span> is the rest of the given list; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span> says that the rest is processed by the
|
|
very function we are defining. As always, we use its signature and its
|
|
purpose statement to figure out the result of this expression. The
|
|
signature tells us that it is a list of numbers, and the purpose statement
|
|
explains that this list represents the list of wages for its input, which
|
|
is the rest of the list of hours.</p></li></ul></div><div class="SIntrapara">The key is to rely on these facts when you formulate the expression that
|
|
computes the result in this case, even if the function is not yet
|
|
defined.</div></p><p><div class="SIntrapara">Since we already have the list of wages for all but the first item of
|
|
<span class="RktSym">whrs</span>, the function must perform two computations to produce the
|
|
expected output for the <span style="font-weight: bold">entire</span> <span class="RktSym">whrs</span>: compute the weekly
|
|
wage for <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span> and construct the list that represents all
|
|
weekly wages for <span class="RktSym">whrs</span>. For the first part, we reuse
|
|
<span class="RktSym">wage</span>. For the second, we <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> the two pieces of
|
|
information together into one list:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">And with that, the definition is complete: see <a href="part_two.html#%28counter._%28figure._fig~3awage%2A%29%29" data-pltdoc="x">figure <span class="FigureRef">64</span></a>.</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"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the weekly wages for all given weekly hours</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">whrs</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the wage for </span><span class="RktSym">h</span><span class="RktCmt"> hours of work</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktSym">h</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3awage*))" x-target-lift="Figure"></a>Figure 64: </span>Computing the wages of all employees</span></p></blockquote><p><a name="(counter._(exercise._raises))"></a><span style="font-weight: bold">Exercise</span> 161. Translate the examples into tests and make sure they
|
|
all succeed. Then change the function in <a href="part_two.html#%28counter._%28figure._fig~3awage%2A%29%29" data-pltdoc="x">figure <span class="FigureRef">64</span></a> so that
|
|
everyone gets $14 per hour. Now revise the entire program so that changing
|
|
the wage for everyone is a single change to the <span style="font-weight: bold">entire</span> program and
|
|
not several. <a href="part_two.html#%28counter._%28exercise._raises%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._fraud))"></a><span style="font-weight: bold">Exercise</span> 162. No employee could possibly work more than 100 hours per
|
|
week. To protect the company against fraud, the function should check that
|
|
no item of the input list of <span class="RktSym">wage*</span> exceeds 100. If one of them
|
|
does, the function should immediately signal an error. How do we have to
|
|
change the function in <a href="part_two.html#%28counter._%28figure._fig~3awage%2A%29%29" data-pltdoc="x">figure <span class="FigureRef">64</span></a> if we want to perform this basic
|
|
reality check? <a href="part_two.html#%28counter._%28exercise._fraud%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span class="refelem"><span class="refcolumn"><span class="refcontent">Show the products of the various steps in the design
|
|
recipe. If you are stuck, show someone how far you got according to the
|
|
<a name="(idx._(gentag._258))"></a>design recipe. The recipe isn’t just a design tool for you to use; it is
|
|
also a diagnosis system so that others can help you help yourself.</span></span></span></p><p><a name="(counter._(exercise._convert.F.C))"></a><span style="font-weight: bold">Exercise</span> 163. Design <span class="RktSym">convertFC</span>. The function converts
|
|
a list of measurements in Fahrenheit to a list of Celsius measurements. <a href="part_two.html#%28counter._%28exercise._convert.F.C%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._convert.D.M))"></a><span style="font-weight: bold">Exercise</span> 164. Design the function <span class="RktSym">convert-euro</span>, which
|
|
converts a list of US$ amounts into a list of € amounts. Look up
|
|
the current exchange rate on the web.</p><p>Generalize <span class="RktSym">convert-euro</span> to the function <span class="RktSym">convert-euro*</span>,
|
|
which consumes an exchange rate and a list of US$ amounts and converts
|
|
the latter into a list of € amounts. <a href="part_two.html#%28counter._%28exercise._convert.D.M%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._subst))"></a><span style="font-weight: bold">Exercise</span> 165. Design the function <span class="RktSym">subst-robot</span>, which consumes
|
|
a list of toy descriptions (one-word strings) and replaces all occurrences of
|
|
<span class="RktVal">"robot"</span> with <span class="RktVal">"r2d2"</span>; all other descriptions remain the same.</p><p>Generalize <span class="RktSym">subst-robot</span> to <span class="RktSym">substitute</span>. The latter
|
|
consumes two strings, called <span class="RktSym">new</span> and <span class="RktSym">old</span>, and a
|
|
list of strings. It produces a new list of strings by substituting all
|
|
occurrences of <span class="RktSym">old</span> with <span class="RktSym">new</span>. <a href="part_two.html#%28counter._%28exercise._subst%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>10.2<tt> </tt><a name="(part._sec~3asil)"></a>Structures in Lists</h4><p>Representing a work week as a number is a bad choice because the printing
|
|
of a paycheck requires more information than hours worked per week. Also,
|
|
not all employees earn the same amount per hour. Fortunately a list may
|
|
contain items other than atomic values; indeed, lists may contain whatever
|
|
values we want, especially structures.</p><p><div class="SIntrapara">Our running example calls for just such a data representation. Instead of
|
|
numbers, we use structures that represent employees plus their work hours
|
|
and pay rates:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">work</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">employee</span><span class="hspace"> </span><span class="RktSym">rate</span><span class="hspace"> </span><span class="RktSym">hours</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A (piece of) </span><a name="(tech._work)"></a><span style="font-style: italic">Work</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym">r</span><span class="stt"> </span><span class="RktSym">h</span><span class="RktPn">)</span><span class="RktCmt"> combines the name </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">with the pay rate </span><span class="RktSym">r</span><span class="RktCmt"> and the number of hours </span><span class="RktSym">h</span></td></tr></table></blockquote></div><div class="SIntrapara">While this representation is still simplistic, it is just enough of an
|
|
additional challenge because it forces us to formulate a data definition
|
|
for lists that contain structures:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a name="(tech._low)"></a><span style="font-style: italic">Low</span><span class="RktCmt"> (short for </span><span style="font-style: italic">list of works</span><span class="RktCmt">) is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">Work</span><span class="stt"> </span><span class="RktSym">Low</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> an instance of </span><span class="RktSym">Low</span><span class="RktCmt"> represents the </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">hours worked for a number of employees</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Here are three elements of <a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="hspace"> </span><span class="RktVal">"Matthew"</span><span class="hspace"> </span><span class="RktVal">12.95</span><span class="hspace"> </span><span class="RktVal">45</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Use the data definition to explain why these pieces of data belong to
|
|
<a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</span></a>.</div></p><p>Stop! Also use the data definition to generate two more examples.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>When you work on real-world projects, you won’t use such
|
|
suffixes; instead you will use a tool for managing different versions
|
|
of code.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">Now that you know that the definition of <a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</span></a> makes sense, it is time
|
|
to redesign the function <span class="RktSym">wage*</span> so that it consumes elements of
|
|
<a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</span></a>, not just lists of numbers: <a name="(idx._(gentag._259))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the weekly wages for the given records</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The suffix “.v2” at the end of the function name informs every reader of
|
|
the code that this is a second, revised version of the function. In this
|
|
case, the revision starts with a new signature and an adapted purpose
|
|
statement. The header is the same as above.</div></p><p>The third step of the design recipe is to work through an example. Let’s
|
|
start with the second list above. It contains one work record, namely,
|
|
<span class="RktPn">(</span><span class="RktSym">make-work</span><span class="stt"> </span><span class="RktVal">"Robby"</span><span class="stt"> </span><span class="RktVal">11.95</span><span class="stt"> </span><span class="RktVal">39</span><span class="RktPn">)</span>. Its interpretation is that
|
|
<span class="RktVal">"Robby"</span> worked for <span class="RktVal">39</span> hours and that he is paid at the
|
|
rate of $11.95 per hour. Hence his wage for the week is $466.05, that is, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktVal">11.95</span><span class="stt"> </span><span class="RktVal">39</span><span class="RktPn">)</span>. The desired result for
|
|
<span class="RktSym">wage*.v2</span> is therefore <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">466.05</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>. Naturally,
|
|
if the input list contained two work records, we would perform this kind
|
|
of computation twice, and the result would be a list of two
|
|
numbers. Stop! Determine the expected result for the third
|
|
data example above.</p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Numbers</span> Keep in mind that BSL—<wbr></wbr>unlike most other programming
|
|
languages—<wbr></wbr>understands decimal numbers just like you do, namely, as exact
|
|
fractions. A language such as Java, for example, would produce 466.04999999999995 for the expected wage of the first work record. Since you
|
|
cannot predict when operations on decimal numbers behave in this strange
|
|
way, you are better off writing down such examples 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">just to prepare yourself for other programming languages. Then again,
|
|
writing down the example in this style also means you have really figured
|
|
out how to compute the wage. <span style="font-weight: bold">End</span></div></p><p><div class="SIntrapara">From here we move on to the development of the template. If you use
|
|
the template questions, you quickly get this much:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">because the data definition consists of two clauses, because it introduces
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> in the first clause and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed structures in the
|
|
second, and so on. But you also realize that you know even more about the
|
|
input than this template expresses. For example, you know that
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span> extracts a structure of three fields from the given
|
|
list. This seems to suggest the addition of three more expressions to the 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-employee</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-rate</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-hours</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This template lists <span style="font-weight: bold">all</span> potentially interesting data.</div></p><p><div class="SIntrapara">We use a different strategy here. Specifically, we suggest that you
|
|
<span style="font-weight: bold">create and refer to a separate function template</span> whenever you
|
|
are
|
|
developing a template for a data definition that refers to other data
|
|
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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">for-work</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._work%29" class="techoutside" data-pltdoc="x"><span class="techinside">Work</span></a><span class="RktCmt"> -> ???</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">a template for processing elements of </span><a href="part_two.html#%28tech._work%29" class="techoutside" data-pltdoc="x"><span class="techinside">Work</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">for-work</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-employee</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-rate</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-hours</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Splitting the templates leads to a natural partition of work into
|
|
functions and among functions; none of them grows too large, and
|
|
all of them relate to a specific data definition.</div></p><p><div class="SIntrapara">Finally, you are ready to program. As always you start with the
|
|
simple-looking case, which is the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line here. If
|
|
<span class="RktSym">wage*.v2</span> is applied to <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, you expect <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>
|
|
back and that settles it. Next you move on to the second line and remind
|
|
yourself of what these expressions compute:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span> extracts the first <span class="RktSym">work</span> structure
|
|
from the list;</p></li><li><p><span class="RktPn">(</span><span class="RktSym">for-work</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span> says that you wish to design a
|
|
function that processes <span class="RktSym">work</span> structures;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span> extracts the rest of the given list; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span> determines the list of wages for
|
|
all the <span class="RktSym">work</span> records other than the first one, according to the
|
|
purpose statement of the function.</p></li></ol></div><div class="SIntrapara">If you are stuck here, use the <a name="(idx._(gentag._260))"></a>table method from <a href="part_two.html#%28counter._%28figure._fig~3adefinition-qb%29%29" data-pltdoc="x">figure <span class="FigureRef">54</span></a>.</div></p><p><div class="SIntrapara">If you understand it all, you see that it is enough to <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> the
|
|
two expressions together:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">for-work</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr></table></blockquote></div><div class="SIntrapara">assuming that <span class="RktSym">for-work</span> computes the wage for the first work
|
|
record. In short, you have finished the function by adding another entry
|
|
to your wish list of functions.</div></p><p><div class="SIntrapara">Since <span class="RktSym">for-work</span> is a name that just serves as a stand-in and since
|
|
it is a bad name for this function, let’s call the function <span class="RktSym">wage.v2</span>
|
|
and write down its complete wish-list entry:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._work%29" class="techoutside" data-pltdoc="x"><span class="techinside">Work</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the wage for the given </span><span class="RktSym">work</span><span class="RktCmt"> record </span><span class="RktSym">w</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage.v2</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The design of this kind of function is extensively covered in
|
|
<a href="part_one.html" data-pltdoc="x">Fixed-Size Data</a> and thus doesn’t need any additional explanation
|
|
here. <a href="part_two.html#%28counter._%28figure._fig~3awage..v2%29%29" data-pltdoc="x">Figure <span class="FigureRef">65</span></a> shows the final result of developing
|
|
<span class="RktSym">wage.v2</span> and <span class="RktSym">wage*.v2</span>.</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"> </span><a href="part_two.html#%28tech._low%29" class="techoutside" data-pltdoc="x"><span class="techinside">Low</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the weekly wages for all weekly work records </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-work</span><span class="hspace"> </span><span class="RktVal">"Robby"</span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">11.95</span><span class="hspace"> </span><span class="RktVal">39</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage*.v2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">an-low</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._work%29" class="techoutside" data-pltdoc="x"><span class="techinside">Work</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">computes the wage for the given </span><span class="RktSym">work</span><span class="RktCmt"> record </span><span class="RktSym">w</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">wage.v2</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-rate</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">work-hours</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3awage..v2))" x-target-lift="Figure"></a>Figure 65: </span>Computing the wages from work records</span></p></blockquote><p><a name="(counter._(exercise._work1))"></a><span style="font-weight: bold">Exercise</span> 166. The <span class="RktSym">wage*.v2</span> function consumes a list of work
|
|
records and produces a list of numbers. Of course, functions may also
|
|
produce lists of structures.</p><p>Develop a data representation for paychecks. Assume that a paycheck
|
|
contains two distinctive pieces of information: the employee’s name
|
|
and an amount. Then design the function <span class="RktSym">wage*.v3</span>. It consumes a
|
|
list of work records and computes a list of paychecks from it, one per
|
|
record.</p><p>In reality, a paycheck also contains an employee number. Develop a data
|
|
representation for employee information and change the data definition for
|
|
work records so that it uses employee information and not just a string
|
|
for the employee’s name. Also change your data representation of paychecks
|
|
so that it contains an employee’s name and number, too. Finally, design
|
|
<span class="RktSym">wage*.v4</span>, a function that maps lists of revised work records to
|
|
lists of revised paychecks.</p><p><span style="font-weight: bold">Note on Iterative Refinement</span> This exercise demonstrates the
|
|
<span style="font-style: italic">iterative refinement</span> of a task. Instead of using data
|
|
representations that include all relevant information, we started from
|
|
simplistic representation of paychecks and gradually made the
|
|
representation realistic. For this simple program, refinement is overkill;
|
|
later we will encounter situations where iterative refinement is not just
|
|
an option but a necessity. <a href="part_two.html#%28counter._%28exercise._work1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._work1..5))"></a><span style="font-weight: bold">Exercise</span> 167. Design the function <span class="RktSym">sum</span>, which consumes a list
|
|
of <span class="RktSym">Posn</span>s and produces the sum of all of its x-coordinates. <a href="part_two.html#%28counter._%28exercise._work1..5%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._work2))"></a><span style="font-weight: bold">Exercise</span> 168. Design the function <span class="RktSym">translate</span>. It consumes and
|
|
produces lists of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. For each <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span> in the
|
|
former, the latter contains <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">x</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">y</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span>. We borrow the word
|
|
“translate” from geometry, where the movement of a point by a constant
|
|
distance along a straight line is called a <span style="font-style: italic">translation</span>. <a href="part_two.html#%28counter._%28exercise._work2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._work3))"></a><span style="font-weight: bold">Exercise</span> 169. Design the function <span class="RktSym">legal</span>. Like
|
|
<span class="RktSym">translate</span> from <a href="part_two.html#%28counter._%28exercise._work2%29%29" data-pltdoc="x">exercise 168</a>, the function consumes and produces
|
|
a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. The result contains all those <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s whose
|
|
x-coordinates are between 0 and 100 and whose y-coordinates
|
|
are between 0 and 200. <a href="part_two.html#%28counter._%28exercise._work3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._work4))"></a><span style="font-weight: bold">Exercise</span> 170. Here is one way to represent a phone number:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">phone</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">area</span><span class="hspace"> </span><span class="RktSym">switch</span><span class="hspace"> </span><span class="RktSym">four</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._phone)"></a><span style="font-style: italic">Phone</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-phone</span><span class="stt"> </span><a href="part_two.html#%28tech._three%29" class="techoutside" data-pltdoc="x"><span class="techinside">Three</span></a><span class="stt"> </span><a href="part_two.html#%28tech._three%29" class="techoutside" data-pltdoc="x"><span class="techinside">Three</span></a><span class="stt"> </span><a href="part_two.html#%28tech._four%29" class="techoutside" data-pltdoc="x"><span class="techinside">Four</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._three)"></a><span style="font-style: italic">Three</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> between </span><span class="RktVal">100</span><span class="RktCmt"> and </span><span class="RktVal">999</span><span class="RktCmt">. </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._four)"></a><span style="font-style: italic">Four</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> between </span><span class="RktVal">1000</span><span class="RktCmt"> and </span><span class="RktVal">9999</span><span class="RktCmt">. </span></td></tr></table></blockquote></div><div class="SIntrapara">Design the function <span class="RktSym">replace</span>. It consumes and produces a list of <a href="part_two.html#%28tech._phone%29" class="techoutside" data-pltdoc="x"><span class="techinside">Phone</span></a>s.
|
|
It replaces all occurrence of area code <span class="RktVal">713</span> with <span class="RktVal">281</span>. <a href="part_two.html#%28counter._%28exercise._work4%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>10.3<tt> </tt><a name="(part._sec~3alis-lis)"></a>Lists in Lists, Files</h4><p><a href="part_one.html#%28part._ch~3afuncs-progs%29" data-pltdoc="x">Functions and Programs</a> introduces <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>, a function for
|
|
reading<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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktSym">2htdp/batch-io</span><span class="RktPn">)</span> to your
|
|
definitions area.</span></span></span>
|
|
an entire text file as a string. In other words, the creator 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> chose to represent text files as strings, and the
|
|
function creates the data representation for specific files (specified by
|
|
a name). Text files aren’t plain long texts or strings, however. They are
|
|
organized into lines and words, rows and cells, and many other ways. In
|
|
short, representing the content of a file as a plain string might work on
|
|
rare occasions but is usually a bad choice.</p><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SubFlow"><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">ttt.txt</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">TTT</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">Put up in a place</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">where it's easy to see</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">the cryptic admonishment</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">T.T.T.</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">When you feel how depressingly</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">slowly you climb,</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">it's well to remember that</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">Things Take Time.</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">Piet Hein</span></p></td></tr><tr><td><p><span class="hspace"> </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~3attt..txt))" x-target-lift="Figure"></a>Figure 66: </span>Things take time</span></p></blockquote><p><div class="SIntrapara">For concreteness, take a look at the sample file in <a href="part_two.html#%28counter._%28figure._fig~3attt..txt%29%29" data-pltdoc="x">figure <span class="FigureRef">66</span></a>.
|
|
It contains a poem by Piet Hein, and it consists of many lines and
|
|
words. When you use the program
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><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-file%29%29" class="RktValLink" data-pltdoc="x">read-file</a></span><span class="hspace"> </span><span class="RktVal">"ttt.txt"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">to turn this file into a BSL string, you get this:<span class="refelem"><span class="refcolumn"><span class="refcontent">The
|
|
dots aren’t really a part of the result, as you probably guessed.</span></span></span>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">"TTT\n \nPut up in a place\nwhere ...."</span></p></blockquote></div><div class="SIntrapara">where the <span class="RktVal">"\n"</span> inside the string indicates line breaks.</div></p><p><div class="SIntrapara">While it is indeed possible to break apart this string with primitive
|
|
operations on strings, for example, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span>, most programming
|
|
languages—<wbr></wbr>including BSL—<wbr></wbr>support many different representations of
|
|
files and functions that create such representations from existing
|
|
files:
|
|
</div><div class="SIntrapara"><ul><li><p><div class="SIntrapara">One way to represent this file is as a list of lines, where each line
|
|
is represented as one string:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"TTT"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">""</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Put up in a place"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Here the second item of the list is the empty string because the file
|
|
contains an empty line.</div></p></li><li><p><div class="SIntrapara">Another way is to use a list of words, again each word represented as
|
|
a string:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"TTT"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Put"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"up"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"in"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Note how the empty second line disappears with this representation. After
|
|
all, there are no words on the empty line.</div></p></li><li><p><div class="SIntrapara">And a third representation relies on lists of lists of words:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"TTT"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Put"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"up"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This representation has an advantage over the second one in that it
|
|
preserves the organization of the file, including the emptiness of the second
|
|
line. The price is that all of a sudden lists contain lists.</div></p></li></ul></div><div class="SIntrapara">While the idea of list-containing lists may sound frightening at first,
|
|
you need not worry. The design recipe helps even with such complications.</div></p><p><div class="SIntrapara"><a name="(idx._(gentag._261))"></a>
|
|
<a name="(idx._(gentag._262))"></a>
|
|
<a name="(idx._(gentag._263))"></a>
|
|
<a name="(idx._(gentag._264))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces the content of file </span><span class="RktSym">f</span><span class="RktCmt"> as a string </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/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="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-string</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces the content of file </span><span class="RktSym">f</span><span class="RktCmt"> as a list of strings, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">one per line</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/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"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-string</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces the content of file </span><span class="RktSym">f</span><span class="RktCmt"> as a list of strings, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">one per word</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%29%29" class="RktValLink" data-pltdoc="x">read-words</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-list-of-string</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces the content of file </span><span class="RktSym">f</span><span class="RktCmt"> as a list of list of</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">strings, one list per line and one string per word </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">The above functions consume the name of a file as 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"> </span><span class="RktCmt">argument. If the specified file does not exist in the </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">same folder as the program, they signal an error.</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aread))" x-target-lift="Figure"></a>Figure 67: </span>Reading files</span></p></blockquote></div></p><p>Before we get started, take a look at <a href="part_two.html#%28counter._%28figure._fig~3aread%29%29" data-pltdoc="x">figure <span class="FigureRef">67</span></a>. It introduces
|
|
a number of useful file reading functions. They are not comprehensive:
|
|
there are many other ways of dealing with text from files, and you will
|
|
need to know a lot more to deal with all possible text files. For our
|
|
purposes here—<wbr></wbr>teaching and learning the principles of systematic program
|
|
design—<wbr></wbr>they suffice, and they empower you to design reasonably
|
|
interesting programs.</p><p><a href="part_two.html#%28counter._%28figure._fig~3aread%29%29" data-pltdoc="x">Figure <span class="FigureRef">67</span></a> uses the names of two
|
|
data definitions that do not exist yet, including one involving
|
|
list-containing lists. As always, we start with a data definition,
|
|
but this time we leave this task to you. Hence, before you read
|
|
on, solve the following exercises. The solutions are needed to make
|
|
complete sense out of the figure, and without working through the
|
|
solutions, you cannot really understand the rest of this section.</p><p><a name="(counter._(exercise._read-dd))"></a><span style="font-weight: bold">Exercise</span> 171. You know what the data definition for
|
|
<a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a> looks like. Spell it out. Make sure that you can
|
|
represent Piet Hein’s poem as an instance of the definition where each
|
|
line is represented as a string and another instance where each word is a
|
|
string. Use <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> and <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%29%29" class="RktValLink" data-pltdoc="x">read-words</a></span> to confirm
|
|
your representation choices.</p><p>Next develop the data definition for <a name="(tech._list._of._list._of._string)"></a><span style="font-style: italic">List-of-list-of-strings</span>.
|
|
Again, represent Piet Hein’s poem as an instance of the definition where
|
|
each line is represented as a list of strings, one per word, and the
|
|
entire poem is a list of such line representations. You may use
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span> to confirm your choice. <a href="part_two.html#%28counter._%28exercise._read-dd%29%29" class="ex-end" data-pltdoc="x"></a></p><p>As you probably know, operating systems come with programs that measure
|
|
files. One counts the number of lines, another determines how many words
|
|
appear per line. Let us start with the latter to illustrate how the design
|
|
recipe helps with the design of complex functions.</p><p><div class="SIntrapara">The first step is to ensure that we have all the necessary data
|
|
definitions. If you solved the above exercise, you have a data definition
|
|
for all possible inputs of the desired function, and the preceding section
|
|
defines <a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>, which describes all possible outputs. To
|
|
keep things short, we use <a href="part_two.html#%28tech._ln%29" class="techoutside" data-pltdoc="x"><span class="techinside">LN</span></a> to refer to the class of lists of
|
|
lists of strings, and use it to write down the header material for the
|
|
desired function: <a name="(idx._(gentag._265))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._ln%29" class="techoutside" data-pltdoc="x"><span class="techinside">LN</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines the number of words on each line </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">lls</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We name the functions <span class="RktSym">words-on-line</span> because it is appropriate
|
|
and captures the purpose statement in one phrase.</div></p><p><div class="SIntrapara">What is really needed, though, is a set of <span style="font-weight: bold">data examples</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">line0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"world"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">line1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">lls0</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">lls1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">line0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">line1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first two definitions introduce two examples of lines: one contains
|
|
two words, the other contains none. The last two definitions show how to
|
|
construct instances of <a href="part_two.html#%28tech._ln%29" class="techoutside" data-pltdoc="x"><span class="techinside">LN</span></a> from these line examples. Determine what
|
|
the expected result is when the function is given these two examples.</div></p><p>Once you have data examples, it is easy to formulate functional
|
|
examples; just imagine applying the function to each of the data
|
|
examples. When you apply <span class="RktSym">words-on-line</span> to <span class="RktSym">lls0</span>, you should
|
|
get the empty list back because there are no lines. When you apply
|
|
<span class="RktSym">words-on-line</span> to <span class="RktSym">lls1</span>, you should get a list of two
|
|
numbers back because there are two lines. The two numbers are
|
|
<span class="RktVal">2</span> and <span class="RktVal">0</span>, respectively, given that the two lines in
|
|
<span class="RktSym">lls1</span> contain two and no words each.</p><p><div class="SIntrapara">Here is how you translate all this into test cases:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">lls0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">lls1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">By doing it at the end of the second step, you have a complete program,
|
|
though running it just fails some of the test cases.</div></p><p><div class="SIntrapara">The development of the template is the interesting step for this sample
|
|
problem. By answering the template questions from <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure <span class="FigureRef">52</span></a>,
|
|
you get the usual list-processing template immediately: <a name="(idx._(gentag._266))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">lls</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">lls</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">lls</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">a list of strings </span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">lls</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">As in the preceding section, we know that the expression <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">lls</span><span class="RktPn">)</span> extracts a <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a>, which has a complex
|
|
organization, too. The temptation is to insert a nested template to express
|
|
this knowledge, but as you should recall, the better idea is to develop a
|
|
second auxiliary template and to change the first line in the second
|
|
condition so that it refers to this auxiliary template.</div></p><p><div class="SIntrapara">Since this auxiliary template is for a function that consumes a list, the
|
|
template looks nearly identical to the previous one: <a name="(idx._(gentag._267))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">line-processor</span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">a string </span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">line-processor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 important differences are that <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span> extracts a string
|
|
from the list, and we consider strings as atomic values. With this
|
|
template in hand, we can change the first line of the second case in
|
|
<span class="RktSym">words-on-line</span> to
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">line-processor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></p></blockquote></div><div class="SIntrapara">which reminds us for the fifth step that the definition for
|
|
<span class="RktSym">words-on-line</span> may demand the design of an auxiliary function.</div></p><p><div class="SIntrapara">Now it is time to program. As always, we use the questions from
|
|
<a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">figure <span class="FigureRef">53</span></a> to guide this step. The first case, concerning
|
|
empty lists of lines, is the easy case. Our examples tell us that the
|
|
answer in this case is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, that is, the empty list of
|
|
numbers. The second case, concerning <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>, contains
|
|
several expressions, and we start with a reminder of what they compute:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span> extracts the first line from the non-empty list
|
|
of (represented) lines;</p></li><li><p><span class="RktPn">(</span><span class="RktSym">line-processor</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span> suggests that we may wish to
|
|
design an auxiliary function to process this line;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span> is the rest of the list of line; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span> computes a list of words per line
|
|
for the rest of the list. How do we know this? We promised just that with
|
|
the signature and the purpose statement for <span class="RktSym">words-on-line</span>.</p></li></ul></div><div class="SIntrapara">Assuming we can design an auxiliary function that consumes a line and
|
|
counts the words on one line—<wbr></wbr>let’s call it <span class="RktSym">words#</span>—<wbr></wbr>it is easy
|
|
to complete the second condition:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words#</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This expression <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>es the number of words on the first line of
|
|
<span class="RktSym">ln</span> onto a list of numbers that represents the number of words on
|
|
the remainder of the lines of <span class="RktSym">ln</span>.</div></p><p><div class="SIntrapara">It remains to design the <span class="RktSym">words#</span> function. Its template is dubbed
|
|
<span class="RktSym">line-processor</span> and its purpose is to count the number of words on
|
|
a line, which is just a list of strings. So here is the wish-list entry:
|
|
<a name="(idx._(gentag._268))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">counts the number of words on </span><span class="RktSym">los</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words#</span><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">At this point, you may recall the example used to illustrate the design
|
|
recipe for self-referential data in <a href="part_two.html#%28part._ch~3adesign-lists%29" data-pltdoc="x">Designing with Self-Referential Data Definitions</a>. The function is
|
|
called <span class="RktSym">how-many</span>, and it too counts the number of strings on a
|
|
list of strings. Even though the input for <span class="RktSym">how-many</span> is supposed
|
|
to represent a list of names, this difference simply doesn’t matter; as
|
|
long as it correctly counts the number of strings on a list of strings,
|
|
<span class="RktSym">how-many</span> solves our problem.</div></p><p><div class="SIntrapara">Since it is good to reuse existing functions, you may define <span class="RktSym">words#</span> 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words#</span><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In reality, however, programming languages come with functions that solve
|
|
such problems already. BSL calls this function <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span>, and it
|
|
counts the number of values on any list of values, no matter what the
|
|
values are.</div></p><p><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._ln)"></a><span style="font-style: italic">LN</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_three.html#%28tech._sim-dd._lo%29" class="techoutside" data-pltdoc="x"><span class="techinside">Los</span></a><span class="stt"> </span><a href="part_two.html#%28tech._ln%29" class="techoutside" data-pltdoc="x"><span class="techinside">LN</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> a list of lines, each is a list of </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">s</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">line0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"hello"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"world"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">line1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ln0</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ln1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">line0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">line1</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._ln%29" class="techoutside" data-pltdoc="x"><span class="techinside">LN</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">determines the number of words on each line </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">ln0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">ln1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">ln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3awords-on-line))" x-target-lift="Figure"></a>Figure 68: </span>Counting the words on a line</span></p></blockquote></div><div class="SIntrapara"><a name="(idx._(gentag._269))"></a></div></p><p><span class="refelem"><span class="refcolumn"><span class="refcontent">You may wish to look over the list of functions that come
|
|
with BSL. Some may look obscure but may become useful in one of the
|
|
upcoming problems. Using such functions saves your time, not ours.</span></span></span></p><p><a href="part_two.html#%28counter._%28figure._fig~3awords-on-line%29%29" data-pltdoc="x">Figure <span class="FigureRef">68</span></a> summarizes the full design for our sample
|
|
problem. The figure includes two test cases. Also, instead of using the
|
|
separate function <span class="RktSym">words#</span>, the definition of
|
|
<span class="RktSym">words-on-line</span> simply calls the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span> function that
|
|
comes with BSL. Experiment with the definition in DrRacket and make sure that
|
|
the two test cases cover the entire function definition.</p><p><div class="SIntrapara">With one small step, you can now design your first file utility:<a name="(idx._(gentag._270))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">counts the words on each line in the given file</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">file-statistic</span><span class="hspace"> </span><span class="RktSym">file-name</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words-on-line</span></td></tr><tr><td><span class="hspace"> </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-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span><span class="hspace"> </span><span class="RktSym">file-name</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It merely composes a teachpack function with
|
|
<span class="RktSym">words-on-line</span>. The former reads a file as a
|
|
<a href="part_two.html#%28tech._list._of._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-list-of-strings</span></a> and hands this value to the latter.</div></p><p>This idea of composing a built-in function with a newly designed function
|
|
is common. Naturally, people don’t design functions randomly and expect to
|
|
find something in the chosen programming language to complement their
|
|
design. Instead, program designers plan ahead and design the function
|
|
<span style="font-weight: bold">to the output</span> that available functions deliver. More generally
|
|
still and as mentioned above, it is common to think about a solution as a
|
|
composition of two computations and to develop an appropriate data
|
|
collection with which to communicate the result of one computation to the
|
|
second one, where each computation is implemented with a function.</p><p><div class="SIntrapara"><a name="(idx._(gentag._271))"></a>
|
|
<a name="(idx._(gentag._272))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts the given </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> to a 3-letter numeric </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">encode-letter</span><span class="hspace"> </span><span class="RktVal">"z"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktVal">"z"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">encode-letter</span><span class="hspace"> </span><span class="RktVal">"\t"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">"00"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktVal">"\t"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">encode-letter</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">"0"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">encode-letter</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3e~3d%29%29" class="RktValLink" data-pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">100</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">"00"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x"><</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">100</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktVal">"0"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts the given </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> into 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="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktVal">"z"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"122"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">code1</span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._number-~3estring%29%29" class="RktValLink" data-pltdoc="x">number->string</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-~3eint%29%29" class="RktValLink" data-pltdoc="x">string->int</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3aencode))" x-target-lift="Figure"></a>Figure 69: </span>Encoding strings</span></p></blockquote></div></p><p><a name="(counter._(exercise._collapse))"></a><span style="font-weight: bold">Exercise</span> 172. Design the function <span class="RktSym">collapse</span>, which converts
|
|
a list of lines into a string. The strings should be separated by blank
|
|
spaces (<span class="RktVal">" "</span>). The lines should be separated with a newline
|
|
(<span class="RktVal">"\n"</span>).</p><p><div class="SIntrapara"><span style="font-weight: bold">Challenge</span> When you are finished, use 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/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._write-file%29%29" class="RktValLink" data-pltdoc="x">write-file</a></span><span class="hspace"> </span><span class="RktVal">"ttt.dat"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">collapse</span><span class="hspace"> </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-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span><span class="hspace"> </span><span class="RktVal">"ttt.txt"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">To make sure the two files <span class="RktVal">"ttt.dat"</span> and <span class="RktVal">"ttt.txt"</span> are
|
|
identical, remove all extraneous white spaces in your version of
|
|
the <span class="stt">T.T.T.</span> poem. <a href="part_two.html#%28counter._%28exercise._collapse%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._no-articles))"></a><span style="font-weight: bold">Exercise</span> 173. Design a program that removes all articles from a
|
|
text file. The program consumes the name <span class="RktSym">n</span> of a file, reads the
|
|
file, removes the articles, and writes the result out to a file whose name
|
|
is the result of concatenating <span class="RktVal">"no-articles-"</span> with <span class="RktSym">n</span>. For this
|
|
exercise, an article is one of the following three words: <span class="RktVal">"a"</span>,
|
|
<span class="RktVal">"an"</span>, and <span class="RktVal">"the"</span>.</p><p>Use <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span> so that the transformation retains the
|
|
organization of the original text into lines and words. When the program is
|
|
designed, run it on the Piet Hein poem. <a href="part_two.html#%28counter._%28exercise._no-articles%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._encode))"></a><span style="font-weight: bold">Exercise</span> 174. Design a program that encodes text files numerically.
|
|
Each letter in a word should be encoded as a numeric three-letter string
|
|
with a value between 0 and 256. <a href="part_two.html#%28counter._%28figure._fig~3aex~3aencode%29%29" data-pltdoc="x">Figure <span class="FigureRef">69</span></a> shows our
|
|
encoding function for single letters. Before you start, explain these
|
|
functions.</p><p><span style="font-weight: bold">Hints</span> (1) Use <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpbatch-io.html#%28def._%28%28lib._2htdp%2Fbatch-io..rkt%29._read-words%2Fline%29%29" class="RktValLink" data-pltdoc="x">read-words/line</a></span> to preserve the organization of
|
|
the file into lines and words. (2) Read up on <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span> again. <a href="part_two.html#%28counter._%28exercise._encode%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._wc))"></a><span style="font-weight: bold">Exercise</span> 175. Design a BSL program that simulates the Unix<span class="refelem"><span class="refcolumn"><span class="refcontent">Unix is an old operating system, which is emulated by Linux, macOS, and to some extent modern Windows.</span></span></span> command
|
|
<span class="stt">wc</span>. The purpose of the command is to count the number of
|
|
<a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s, words, and lines in a given file. That is, the command
|
|
consumes the name of a file and produces a value that consists of three
|
|
numbers. (Why might your computer’s <span class="stt">wc</span> give a slightly different result from your code?) <a href="part_two.html#%28counter._%28exercise._wc%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"> </span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">transposes the given matrix along the diagonal </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">wor1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">11</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">21</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">wor2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">22</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">tam1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">wor1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">wor2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">transpose</span><span class="hspace"> </span><span class="RktSym">mat1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">tam1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">transpose</span><span class="hspace"> </span><span class="RktSym">lln</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">lln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">first*</span><span class="hspace"> </span><span class="RktSym">lln</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">transpose</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rest*</span><span class="hspace"> </span><span class="RktSym">lln</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aex~3atranspose))" x-target-lift="Figure"></a>Figure 70: </span>Transpose a matrix</span></p></blockquote><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3atranspose))"></a><span style="font-weight: bold">Exercise</span> 176. Mathematics teachers may have introduced you to
|
|
matrix calculations by now. In principle, matrix just means rectangle of
|
|
numbers. Here is one possible data representation for matrices: <a name="(idx._(gentag._273))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._matrix)"></a><span style="font-style: italic">Matrix</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a><span class="stt"> </span><a href="part_two.html#%28tech._matrix%29" class="techoutside" data-pltdoc="x"><span class="techinside">Matrix</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">constraint</span><span class="RktCmt"> all rows in matrix are of the same length</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._row)"></a><span style="font-style: italic">Row</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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><a href="part_two.html#%28tech._row%29" class="techoutside" data-pltdoc="x"><span class="techinside">Row</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Note the constraints on matrices. Study the data definition and translate
|
|
the two-by-two matrix consisting of the numbers 11, 12, 21, and 22 into this
|
|
data representation. Stop, don’t read on until you have figured out the
|
|
data examples.</div></p><p><div class="SIntrapara">Here is the solution for the five-second puzzle:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">row1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">11</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">row2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">21</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">22</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">mat1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">row1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">row2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you didn’t create it yourself, study it now.</div></p><p>The function in <a href="part_two.html#%28counter._%28figure._fig~3aex~3atranspose%29%29" data-pltdoc="x">figure <span class="FigureRef">70</span></a> implements the important
|
|
mathematical operation of transposing the entries in a matrix. To
|
|
transpose means to mirror the entries along the diagonal, that is, the
|
|
line from the top-left to the bottom-right.</p><p>Stop! Transpose <span class="RktSym">mat1</span> by hand, then read
|
|
<a href="part_two.html#%28counter._%28figure._fig~3aex~3atranspose%29%29" data-pltdoc="x">figure <span class="FigureRef">70</span></a>. Why does <span class="RktSym">transpose</span> ask
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">lln</span><span class="RktPn">)</span><span class="RktPn">)</span>?</p><p><div class="SIntrapara">The definition assumes two auxiliary functions:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">first*</span>, which consumes a matrix and produces the first
|
|
column as a list of numbers; and</p></li><li><p><span class="RktSym">rest*</span>, which consumes a matrix and removes the first
|
|
column. The result is a matrix.</p></li></ul></div></p><p>Even though you lack definitions for these functions, you should be able to
|
|
understand how <span class="RktSym">transpose</span> works. You should also understand that
|
|
you <span style="font-weight: bold">cannot</span> design this function with the design recipes you have
|
|
seen so far. Explain why.</p><p>Design the two wish-list functions. Then complete the design of
|
|
<span class="RktSym">transpose</span> with some test cases. <a href="part_two.html#%28counter._%28exercise._ex~3atranspose%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>10.4<tt> </tt><a name="(part._list-edit2._sec~3aedit2)"></a>A Graphical Editor, Revisited</h4><p><a href="part_one.html#%28part._sec~3aedit1%29" data-pltdoc="x">A Graphical Editor</a> is about the design of an interactive graphical one-line
|
|
editor. It suggests two different ways to represent the state of the
|
|
editor and urges you to explore both: a structure that contains a pair of
|
|
strings or a structure that combines a string with an index to a current
|
|
position (see <a href="part_one.html#%28counter._%28exercise._struct-edit4%29%29" data-pltdoc="x">exercise 87</a>).</p><p><div class="SIntrapara">A third alternative is to use structures that combine two lists of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">editor</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">pre</span><span class="hspace"> </span><span class="RktSym">post</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._list-edit2._editor)"></a><span style="font-style: italic">Editor</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="stt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1S</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1S</span></a><span class="RktPn">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._list-edit2._lo1)"></a><span style="font-style: italic">Lo1S</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1S</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Before you wonder why, let’s make up two 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">good</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"g"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"o"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"o"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">all</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"l"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"l"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">lla</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"l"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"l"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">data example 1: </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktSym">all</span><span class="hspace"> </span><span class="RktSym">good</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">data example 2:</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktSym">lla</span><span class="hspace"> </span><span class="RktSym">good</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The two examples demonstrate how important it is to write down an
|
|
interpretation. While the two fields of an editor clearly represent the
|
|
letters to the left and right of the cursor, the two examples demonstrate
|
|
that there are at least two ways to interpret the structure types:
|
|
</div><div class="SIntrapara"><ol><li><p><div class="SIntrapara"><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="stt"> </span><span class="RktSym">pre</span><span class="stt"> </span><span class="RktSym">post</span><span class="RktPn">)</span> could mean the letters in
|
|
<span class="RktSym">pre</span> precede the cursor and those in <span class="RktSym">post</span> succeed it and
|
|
that the combined text 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace"> </span><span class="RktSym">pre</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace"> </span><span class="RktSym">post</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Recall that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span> turns a list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s into a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>.</div></p></li><li><p><div class="SIntrapara"><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="stt"> </span><span class="RktSym">pre</span><span class="stt"> </span><span class="RktSym">post</span><span class="RktPn">)</span> could equally well mean that the
|
|
letters in <span class="RktSym">pre</span> precede the cursor in <span style="font-weight: bold">reverse</span> order. If
|
|
so, we obtain the text in the displayed editor 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-append%29%29" class="RktValLink" data-pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktSym">pre</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace"> </span><span class="RktSym">post</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The function <span class="RktSym">rev</span> must consume a list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s and
|
|
reverse it.</div></p></li></ol></div><div class="SIntrapara">Even without a complete definition for <span class="RktSym">rev</span>, you can imagine how it
|
|
works. Use this understanding to make sure you understand that
|
|
translating the first data example into information according to the
|
|
first interpretation and treating the second data example according to the
|
|
second interpretation yields the same editor display:
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img style="vertical-align: -0.0px; margin: -3px -3px -3px -3px;" src="pict_101.png" alt="image" width="206.0" height="26.0"/></p></blockquote></div></p><p>Both interpretations are fine choices, but it turns out that using the
|
|
second one greatly simplifies the design of the program. The rest of this
|
|
section demonstrates this point, illustrating the use of lists inside
|
|
of structures at the same time. To appreciate the lesson properly, you
|
|
should have solved the exercises in <a href="part_one.html#%28part._sec~3aedit1%29" data-pltdoc="x">A Graphical Editor</a>.</p><p><div class="SIntrapara">Let’s start with <span class="RktSym">rev</span> because we clearly need this function to
|
|
make sense out of the data definition. Its header material is
|
|
straightforward:<a name="(idx._list-edit2._(gentag._274._list-edit2))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1s</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1s</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a reverse version of the given list </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">For good measure, we have added one “obvious” example as a test
|
|
case. You may want to add some extra examples just to make sure you
|
|
understand what is needed.</div></p><p><div class="SIntrapara">The template for <span class="RktSym">rev</span> is the usual list 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">There are two cases, and the second case comes with several selector
|
|
expressions and a self-referential one.</div></p><p><div class="SIntrapara">Filling in the template is easy for the first clause: the reverse version
|
|
of the empty list is the empty list. For the second clause, we once again
|
|
use the coding questions:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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 first item on the list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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> is the rest of the list; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">rev</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> is the reverse of the rest of the list.</p></li></ul></div><div class="SIntrapara">Stop! Try to finish the design of <span class="RktSym">rev</span> with these hints.</div></p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;"><p><span class="RktSym">l</span></p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr></table></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr></table></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">rev</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td style="border-bottom: 1px solid black;"><p><span class="hspace"> </span></p></td><td style="border-bottom: 1px solid black;"><p><span class="RktPn">(</span><span class="RktSym">rev</span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span></p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">"a"</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td colspan="9"><p></p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktVal">"a"</span></p></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><p><span class="hspace"> </span></p></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._list-edit2._(figure._fig~3afk-for-rev))" x-target-lift="Figure"></a>Figure 71: </span>Tabulating for <span class="RktSym">rev</span></span></p></blockquote><p><div class="SIntrapara">If these hints leave you stuck, remember to create a <a name="(idx._list-edit2._(gentag._275._list-edit2))"></a>table from the
|
|
examples. <a href="part_two.html#%28counter._list-edit2._%28figure._fig~3afk-for-rev%29%29" data-pltdoc="x">Figure <span class="FigureRef">71</span></a> shows the table for two examples:
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </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> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"c"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>. The second example is particularly illustrative. A look at the
|
|
next to last column shows that <span class="RktPn">(</span><span class="RktSym">rev</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> accomplishes most
|
|
of the work by producing <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"c"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span>. Since the
|
|
desired result is <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"c"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </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><span class="RktPn">)</span><span class="RktPn">)</span>,
|
|
<span class="RktSym">rev</span> must somehow add <span class="RktVal">"a"</span> to the end of the result of the
|
|
recursion. Indeed, because <span class="RktPn">(</span><span class="RktSym">rev</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span> is always the reverse of the
|
|
rest of the list, it clearly suffices to add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">l</span><span class="RktPn">)</span> to its
|
|
end. While we don’t have a function that adds items to the end of a list,
|
|
we can wish for it and use it to complete the 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">rev</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Here is the extended wish-list entry for <span class="RktSym">add-at-end</span>:<a name="(idx._list-edit2._(gentag._276._list-edit2))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1s</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1s</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a new list by adding </span><span class="RktSym">s</span><span class="RktCmt"> to the end of </span><span class="RktSym">l</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It is “extended” because it comes with an example formulated as a test
|
|
case. The example is derived from the example for <span class="RktSym">rev</span>, and
|
|
indeed, it is precisely the example that motivates the wish-list entry.
|
|
Make up an example where <span class="RktSym">add-at-end</span> consumes an empty list before
|
|
you read on.</div></p><p><div class="SIntrapara">Since <span class="RktSym">add-at-end</span> is also a list-processing function, the template
|
|
is just a renaming of the one you know so well now:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">To complete it into a function definition, we proceed according to
|
|
the recipe questions for step 5. Our first question is to formulate an
|
|
answer for the “basic” case, that is, the first case here. If you
|
|
worked through the suggested exercise, you know that the result of
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">is always <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">s</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>. After all, the result must be a list
|
|
and the list must contain the given <span class="RktSym">1String</span>.</div></p><p><div class="SIntrapara">The next two questions concern the “complex” or “self-referential”
|
|
case. We know what the expressions in the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line
|
|
compute: the first expression extracts the first <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a> from the
|
|
given list and the second expression “creates a new list by adding
|
|
<span class="RktSym">s</span> to the end of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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>.” That is, the purpose
|
|
statement dictates what the function must produce here. From here, it is
|
|
clear that the function must add <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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> back to the result of
|
|
the recursion:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktSym">l</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">add-at-end</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Run the tests-as-examples to reassure yourself that this function works
|
|
and that therefore <span class="RktSym">rev</span> works, too. Of course, you shouldn’t be
|
|
surprised to find out that BSL already provides a function that reverses
|
|
any given list, including lists of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s. And naturally, it is
|
|
called <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span>.</div></p><p><a name="(counter._list-edit2._(exercise._create-editor))"></a><span style="font-weight: bold">Exercise</span> 177. Design the function <span class="RktSym">create-editor</span>. The
|
|
function consumes two strings and produces an <a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>. The first
|
|
string is the text to the left of the cursor and the second string is the
|
|
text to the right of the cursor. The rest of the section relies on this
|
|
function. <a href="part_two.html#%28counter._list-edit2._%28exercise._create-editor%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">At this point, you should have a complete understanding of our
|
|
data representation for the graphical one-line editor. Following the
|
|
design strategy for interactive programs from <a href="part_one.html#%28part._.D.K._sec~3adesign-world%29" data-pltdoc="x">Designing World Programs</a>, you
|
|
should define physical constants—<wbr></wbr>the width and height of the editor, for
|
|
example—<wbr></wbr>and graphical constants—<wbr></wbr>for example, the cursor. Here are ours:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the height of the editor </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktVal">200</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">its width </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktVal">16</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the font size </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="hspace"> </span><span class="RktVal">"black"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the font color </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktSym">HEIGHT</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">CURSOR</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._rectangle%29%29" class="RktValLink" data-pltdoc="x">rectangle</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The important point, however, is to write down the wish list for your
|
|
event handler(s) and your function that draws the state of the
|
|
editor. Recall that <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/universe</span></span> teachpack</span> dictates the header
|
|
material for these functions
|
|
<a name="(idx._list-edit2._(gentag._277._list-edit2))"></a>:
|
|
<a name="(idx._list-edit2._(gentag._278._list-edit2))"></a>
|
|
<a name="(idx._list-edit2._(gentag._279._list-edit2))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders an editor as an image of the two texts </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">separated by the cursor </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-render</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">deals with a key event, given some editor</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-kh</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In addition, <a href="part_one.html#%28part._.D.K._sec~3adesign-world%29" data-pltdoc="x">Designing World Programs</a> demands that you write down a main
|
|
function for your program:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">main : </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">launches the editor given some initial string </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">main</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">""</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">editor-kh</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">editor-render</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Reread <a href="part_two.html#%28counter._list-edit2._%28exercise._create-editor%29%29" data-pltdoc="x">exercise 177</a> to determine the initial editor for
|
|
this program.</div></p><p><div class="SIntrapara">While it does not matter which wish you tackle next, we choose to design
|
|
<span class="RktSym">editor-kh</span> first and <span class="RktSym">editor-render</span> second. Since we have
|
|
the header material, let’s explain the functioning of the key-event
|
|
handler with two 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-kh</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktVal">""</span><span class="hspace"> </span><span class="RktVal">""</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-kh</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktVal">"cd"</span><span class="hspace"> </span><span class="RktVal">"fgh"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktVal">"cde"</span><span class="hspace"> </span><span class="RktVal">"fgh"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Both of these examples demonstrate what happens when you press the letter
|
|
“e” on your keyboard. The computer runs the function <span class="RktSym">editor-kh</span>
|
|
on the current state of the editor and <span class="RktVal">"e"</span>. In the first example,
|
|
the editor is empty, which means that the result is an editor with just
|
|
the letter <span class="RktVal">"e"</span> in it followed by the cursor. In the second
|
|
example, the cursor is between the strings <span class="RktVal">"cd"</span> and
|
|
<span class="RktVal">"fgh"</span>, and therefore the result is an editor with the cursor
|
|
between <span class="RktVal">"cde"</span> and <span class="RktVal">"fgh"</span>. In short, the function always
|
|
inserts any normal letter at the cursor position.</div></p><p>Before you read on, you should make up examples that illustrate how
|
|
<span class="RktSym">editor-kh</span> works when you press the backspace (<span class="RktVal">"\b"</span>) key
|
|
to delete some letter, the <span class="RktVal">"left"</span> and <span class="RktVal">"right"</span> arrow keys
|
|
to move the cursor, or some other arrow keys. In all cases, consider what
|
|
should happen when the editor is empty, when the cursor is at the left end
|
|
or right end of the non-empty string in the editor, and when it is in the
|
|
middle. Even though you are not working with intervals here, it is still a
|
|
good idea to develop examples for the “extreme” cases.</p><p>Once you have test cases, it is time to develop the template. In the case
|
|
of <span class="RktSym">editor-kh</span> you are working with a function that consumes two
|
|
complex forms of data: one is a structure containing lists, the other one
|
|
is a large enumeration of strings. Generally speaking, this design case
|
|
calls for an improved design recipe; but in cases like these, it is also
|
|
clear that you should deal with one of the inputs first, namely, the
|
|
keystroke.</p><p><div class="SIntrapara">Having said that, the template is just a large <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression for
|
|
checking which <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a> the function received:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-kh</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"left"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"right"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\b"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\t"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\r"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-length%29%29" class="RktValLink" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression doesn’t quite match the data definition for
|
|
<a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a> because some <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a>s need special attention
|
|
(<span class="RktVal">"left"</span>, <span class="RktVal">"\b"</span>, and so on), some need to
|
|
be ignored because they are special (<span class="RktVal">"\t"</span> and <span class="RktVal">"\r"</span>), and
|
|
some should be classified into one large group (ordinary keys).</div></p><p><a name="(counter._list-edit2._(exercise._editor-explain))"></a><span style="font-weight: bold">Exercise</span> 178. Explain why the template for <span class="RktSym">editor-kh</span>
|
|
deals with <span class="RktVal">"\t"</span> and <span class="RktVal">"\r"</span> before it checks for strings of
|
|
length <span class="RktVal">1</span>. <a href="part_two.html#%28counter._list-edit2._%28exercise._editor-explain%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">For the fifth step—<wbr></wbr>the definition of the function—<wbr></wbr>we tackle each clause
|
|
in the conditional separately. The first clause demands a result that
|
|
moves the cursor and leaves the string content of the editor alone. So
|
|
does the second clause. The third clause, however, demands the deletion of
|
|
a letter from the editor’s content—<wbr></wbr>if there is a letter. Last, the sixth
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause concerns the addition of letters at the cursor
|
|
position. Following the first basic <a name="(idx._list-edit2._(gentag._280._list-edit2))"></a>guideline, we make extensive use of a
|
|
wish-list and imagine one function per task:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-kh</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"left"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-lft</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"right"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-rgt</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\b"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-del</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\t"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28def._world._%28%28lib._2htdp%2Funiverse..rkt%29._key~3d~3f%29%29" class="RktValLink" data-pltdoc="x">key=?</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktVal">"\r"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string-length%29%29" class="RktValLink" data-pltdoc="x">string-length</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">As you can tell from the definition of <span class="RktSym">editor-kh</span>, three of the
|
|
four wish-list functions have the same signature:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> </span></p></blockquote></div><div class="SIntrapara">The last one takes two arguments instead of one:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></p></blockquote></div><div class="SIntrapara">We leave the proper formulation of wishes for the first three functions to
|
|
you and focus on the fourth one.</div></p><p><div class="SIntrapara">Let’s start with a purpose statement and a function header:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">insert the </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> </span><span class="RktSym">k</span><span class="RktCmt"> between </span><span class="RktSym">pre</span><span class="RktCmt"> and </span><span class="RktSym">post</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The purpose is straight out of the problem statement. For the construction
|
|
of a function header, we need an instance of <a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>. Since
|
|
<span class="RktSym">pre</span> and <span class="RktSym">post</span> are the pieces of the current one, we just
|
|
put them back together.</div></p><p><div class="SIntrapara">Next we derive examples for <span class="RktSym">editor-ins</span> from those for
|
|
<span class="RktSym">editor-kh</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"f"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"g"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"f"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"g"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You should work through these examples using the interpretation of
|
|
<a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>. That is, make sure you understand what the given editor
|
|
means in terms of information and what the function call is supposed to
|
|
achieve in those terms. In this particular case, it is best to draw the
|
|
visual representation of the editor because it represents the information
|
|
well.</div></p><p><div class="SIntrapara">The fourth step demands the development of the template. The first argument
|
|
is guaranteed to be a structure, and the second one is a string, an atomic
|
|
piece of data. In other words, the template just pulls out the pieces from
|
|
the given editor 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Remember a template lists parameters because they are available, too.</div></p><p><div class="SIntrapara">From the template and the examples, it is relatively easy to conclude that
|
|
<span class="RktSym">editor-ins</span> is supposed to create an editor from the given
|
|
editor’s <span class="RktSym">pre</span> and <span class="RktSym">post</span> fields with <span class="RktSym">k</span> added to
|
|
the front of the former:
|
|
<a name="(idx._list-edit2._(gentag._281._list-edit2))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-ins</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="hspace"> </span><span class="RktSym">k</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-editor</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">k</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Even though both <span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="stt"> </span><span class="RktSym">ed</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="stt"> </span><span class="RktSym">ed</span><span class="RktPn">)</span>
|
|
are lists of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s, there is no need to design auxiliary
|
|
functions. To get the desired result, it suffices to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>,
|
|
which creates lists.</div></p><p>At this point, you should do two things. First, run the tests for this
|
|
function. Second, use the interpretation of <span class="RktSym">Editor</span> and explain
|
|
abstractly why this function performs the insertion. And as if this isn’t
|
|
enough, you may wish to compare this simple definition with the one from
|
|
<a href="part_one.html#%28counter._%28exercise._struct-edit1%29%29" data-pltdoc="x">exercise 84</a> and figure out why the other one needs an auxiliary
|
|
function while our definition here doesn’t.</p><p><div class="SIntrapara"><a name="(counter._list-edit2._(exercise._editor-list-rev-aux))"></a><span style="font-weight: bold">Exercise</span> 179. Design the functions
|
|
<a name="(idx._list-edit2._(gentag._282._list-edit2))"></a>
|
|
<a name="(idx._list-edit2._(gentag._283._list-edit2))"></a>
|
|
<a name="(idx._list-edit2._(gentag._284._list-edit2))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">moves the cursor position one </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> left, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">if possible </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-lft</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">moves the cursor position one </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> right, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">if possible </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-rgt</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">deletes a </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt"> to the left of the cursor,</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">if possible </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-del</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Again, it is critical that you work through a good range of examples. <a href="part_two.html#%28counter._list-edit2._%28exercise._editor-list-rev-aux%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara">Designing the rendering function for <a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>s poses some new but
|
|
small challenges. The first one is to develop a sufficiently large number
|
|
of test cases. On the one hand, it demands coverage of the possible
|
|
combinations: an empty string to the left of the cursor, an empty one on
|
|
the right, and both strings empty. On the other hand, it also requires
|
|
some experimenting with the functions that the <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/image</span></span> teachpack</span> teachpack
|
|
provides. Specifically, it needs a way to compose the two pieces of
|
|
strings rendered as text images, and it needs a way of placing the text
|
|
image into the empty image frame (<span class="RktSym">MT</span>). Here is what we do to
|
|
create an image for the result of <span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="stt"> </span><span class="RktVal">"pre"</span><span class="stt"> </span><span class="RktVal">"post"</span><span class="RktPn">)</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%2Falign%29%29" class="RktValLink" data-pltdoc="x">place-image/align</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace"> </span><span class="RktVal">"pre"</span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">CURSOR</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace"> </span><span class="RktVal">"post"</span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"left"</span><span class="hspace"> </span><span class="RktVal">"top"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">MT</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If you compare this with the editor image above, you notice some
|
|
differences, which is fine because the exact layout isn’t essential to the
|
|
purpose of this exercise, and because the revised layout doesn’t
|
|
trivialize the problem. In any case, do experiment in the interactions
|
|
area of DrRacket to find your favorite editor display.</div></p><p><div class="SIntrapara">You are now ready to develop the template, and you should come up with this
|
|
much: <a name="(idx._list-edit2._(gentag._285._list-edit2))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-render</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The given argument is just a structure type with two fields. Their values,
|
|
however, are lists of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s, and you might be tempted to refine
|
|
the template even more. Don’t! Instead, keep in mind that when one
|
|
data definition refers to another complex data definition, you are better
|
|
off using the wish list.</div></p><p><div class="SIntrapara">If you have worked through a sufficient number of examples, you also know
|
|
what you want on your wish list: one function that turns a string into a
|
|
text of the right size and color. Let’s call this function
|
|
<span class="RktSym">editor-text</span>. Then the definition of <span class="RktSym">editor-render</span> just
|
|
uses <span class="RktSym">editor-text</span> twice and then composes the result with
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%29%29" class="RktValLink" data-pltdoc="x">place-image</a></span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-render</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%2Falign%29%29" class="RktValLink" data-pltdoc="x">place-image/align</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">CURSOR</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="hspace"> </span><span class="RktSym">e</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"left"</span><span class="hspace"> </span><span class="RktVal">"top"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">MT</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Although this definition nests expressions three levels deep, the use of
|
|
the imaginary <span class="RktSym">editor-text</span> function renders it quite readable.</div></p><p><div class="SIntrapara">What remains is to design <span class="RktSym">editor-text</span>. From the design of
|
|
<span class="RktSym">editor-render</span>, we know that <span class="RktSym">editor-text</span> consumes a
|
|
list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s and produces a text image:<a name="(idx._list-edit2._(gentag._286._list-edit2))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list-edit2._lo1%29" class="techoutside" data-pltdoc="x"><span class="techinside">Lo1s</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders a list of </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">s as a text image </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace"> </span><span class="RktVal">""</span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This dummy definition produces an empty text image.</div></p><p><div class="SIntrapara">To demonstrate what <span class="RktSym">editor-text</span> is supposed to compute, we work
|
|
through an example. The example input is
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">create-editor</span><span class="hspace"> </span><span class="RktVal">"pre"</span><span class="hspace"> </span><span class="RktVal">"post"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">which was also used to explain <span class="RktSym">editor-render</span> and is equivalent to
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">make-editor</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"p"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"p"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"o"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"s"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"t"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">We pick the second list as our sample input for <span class="RktSym">editor-text</span>, and
|
|
we know the expected result from the example for <span class="RktSym">editor-render</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"p"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"o"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"s"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"t"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace"> </span><span class="RktVal">"post"</span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You may wish to make up a second example before reading on.</div></p><p><div class="SIntrapara">Given that <span class="RktSym">editor-text</span> consumes a list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s, we can
|
|
write down the template without much ado:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">After all, the template is dictated by the data definition that describes
|
|
the function input. But you don’t need the template if you understand and
|
|
keep in mind the interpretation for <a href="part_two.html#%28tech._list-edit2._editor%29" class="techoutside" data-pltdoc="x"><span class="techinside">Editor</span></a>. It uses
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span> to turn a string into a list of
|
|
<a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s. Naturally, there is a function <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span> that
|
|
performs the inverse computation, that is,
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"p"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"o"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"s"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"t"</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">"post"</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Using this function, the definition of <span class="RktSym">editor-text</span> is just a
|
|
small step from the example to the function body:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._text%29%29" class="RktValLink" data-pltdoc="x">text</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">FONT-SIZE</span><span class="hspace"> </span><span class="RktSym">FONT-COLOR</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><a name="(counter._list-edit2._(exercise._editor-implode-manually))"></a><span style="font-weight: bold">Exercise</span> 180. Design <span class="RktSym">editor-text</span> without
|
|
using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._implode%29%29" class="RktValLink" data-pltdoc="x">implode</a></span>. <a href="part_two.html#%28counter._list-edit2._%28exercise._editor-implode-manually%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">The true surprise comes when you test the two functions. While our test for
|
|
<span class="RktSym">editor-text</span> succeeds, the test for <span class="RktSym">editor-render</span>
|
|
fails. An inspection of the failure shows that the string to the left of
|
|
the cursor—<wbr></wbr> <span class="RktVal">"pre"</span>—<wbr></wbr>is typeset backward. We forgot that this
|
|
part of the editor’s state is represented in reverse. Fortunately, the
|
|
<a name="(idx._list-edit2._(gentag._287._list-edit2))"></a>unit tests for the two functions pinpoint which function is wrong and even
|
|
tell us what is wrong with the function and suggest how to fix the problem:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-render</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._place-image%2Falign%29%29" class="RktValLink" data-pltdoc="x">place-image/align</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._beside%29%29" class="RktValLink" data-pltdoc="x">beside</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-pre</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">CURSOR</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-text</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">editor-post</span><span class="hspace"> </span><span class="RktSym">ed</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"left"</span><span class="hspace"> </span><span class="RktVal">"top"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">MT</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This definition uses the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._reverse%29%29" class="RktValLink" data-pltdoc="x">reverse</a></span> function on the <span class="RktSym">pre</span> field of
|
|
<span class="RktSym">ed</span>.</div></p><p><span style="font-weight: bold">Note</span> Modern applications allow users to position the cursor with the
|
|
mouse (or other gesture-based devices). While it is in principle possible
|
|
to add this capability to your editor, we wait with doing so until
|
|
<a href="part_six.html#%28part._accu-edit._sec~3aedit3%29" data-pltdoc="x">A Graphical Editor, with Mouse</a>.</p><h3>11<tt> </tt><a name="(part._ch~3alist-sort)"></a>Design by Composition</h3><p>By now you know that programs are complex products and that their
|
|
production requires the design of many collaborating functions. This
|
|
collaboration works well if the designer knows when to design several
|
|
functions and how to compose these functions into one program.</p><p>You have encountered this need to design interrelated functions several
|
|
times. Sometimes a problem statement implies several different tasks, and
|
|
each task is best realized with a function. At other times, a data
|
|
definition may refer to another one, and in that case, a function
|
|
processing the former kind of data relies on a function processing the
|
|
latter.</p><p>In this chapter, we present several scenarios that call for the design of
|
|
programs that compose many functions. To support this kind of <a name="(idx._(gentag._288))"></a>design, the
|
|
chapter presents some informal <a name="(idx._(gentag._289))"></a>guidelines on divvying up functions and
|
|
composing them. Since these examples demand complex forms of lists,
|
|
however, this chapter starts with a section on concise list notation.</p><h4>11.1<tt> </tt><a name="(part._sec~3aabbrev)"></a>The <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> Function</h4><p>At this point, you should have tired of writing so many <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>es
|
|
just to create a list, especially for lists that contain a bunch of
|
|
values. Fortunately, we have an additional teaching language for you
|
|
that<span class="refelem"><span class="refcolumn"><span class="refcontent">You have graduated from BSL. It is time to use the
|
|
“Language” menu and to select “Beginning Student with List
|
|
Abbreviations” for your studies.</span></span></span> provides mechanisms for simplifying
|
|
this part of a programmer’s life. BSL+ does so, too.</p><p><div class="SIntrapara">The key innovation is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>, which consumes an
|
|
arbitrary number of values and creates a list. The simplest way to
|
|
understand <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> is to think of it as an
|
|
abbreviation. Specifically, every expression of the shape
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">exp-1</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">exp-n</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">stands for a series of <span style="font-style: italic">n</span> <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">exp-1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">exp-n</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Keep in mind that <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> is not an item of the list here, but
|
|
actually the rest of the list. Here is a table with three examples:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><p>short-hand</p></td><td><p><span class="hspace"> </span></p></td><td><p>long-hand</p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"ABC"</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"ABC"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktVal">#true</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#true</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span></p></td><td><p><span class="hspace"> </span></p></td><td><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">They introduce lists with one, two, and three items, respectively.</div></p><p><div class="SIntrapara">Of course, we can apply <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> not only to values but also
|
|
to expressions:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list 1 2)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2F%29%29" class="RktValLink" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">/:division by zero</span></p></td></tr></table></blockquote></div><div class="SIntrapara">Before the list is constructed, the expressions must be evaluated.
|
|
If during the evaluation of an expression an error occurs, the list
|
|
is never formed. In short, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> behaves just like any other
|
|
primitive operation that consumes an arbitrary number of arguments; its
|
|
result just happens to be a list constructed with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>es.</div></p><p><div class="SIntrapara">The use of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> greatly simplifies the notation for lists
|
|
with many items and lists that contain lists or structures. Here
|
|
is an 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">9</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">This list contains 10 items and its formation with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>
|
|
would require 10 uses of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and one instance of
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. Similarly, the list
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"bob"</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"carl"</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"dana"</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"erik"</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"frank"</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"grant"</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"hank"</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"ian"</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"john"</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"karel"</span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">requires 11 uses of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>, which sharply contrasts with 40
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and 11 additional uses of <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist-cons3))"></a><span style="font-weight: bold">Exercise</span> 181. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> to construct the equivalent of these lists:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"c"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"d"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"hello"</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Also try your hand at this one:
|
|
</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="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">Start by determining how many items each list and each nested list
|
|
contains. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> to express your answers; this ensures
|
|
that your abbreviations are really the same as the long-hand. <a href="part_two.html#%28counter._%28exercise._ex~3alist-cons3%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist-cons2))"></a><span style="font-weight: bold">Exercise</span> 182. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> to form the equivalent of these lists:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">5</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"he"</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"it"</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"lui"</span><span class="stt"> </span><span class="RktVal">14</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> to express your answers. <a href="part_two.html#%28counter._%28exercise._ex~3alist-cons2%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist-cons4))"></a><span style="font-weight: bold">Exercise</span> 183. On some occasions lists are formed with
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>.
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal">#false</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">13</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">13</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">#false</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Reformulate each of the following expressions using only <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>
|
|
or only <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>. Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> to check your answers. <a href="part_two.html#%28counter._%28exercise._ex~3alist-cons4%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist-cons1))"></a><span style="font-weight: bold">Exercise</span> 184. Determine the values of the following expressions:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="stt"> </span><span class="RktVal">"a"</span><span class="stt"> </span><span class="RktVal">"b"</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">#false</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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">20</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%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">20</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2F%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">20</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"dana"</span><span class="stt"> </span><span class="RktVal">"jane"</span><span class="stt"> </span><span class="RktVal">"mary"</span><span class="stt"> </span><span class="RktVal">"laura"</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> to express your answers. <a href="part_two.html#%28counter._%28exercise._ex~3alist-cons1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3alist-cons5))"></a><span style="font-weight: bold">Exercise</span> 185. You know about <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> from BSL, but BSL+
|
|
comes with even more selectors than that. Determine the values of the
|
|
following expressions:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></p></li></ol></div><div class="SIntrapara">Find out from the documentation whether <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span> and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._fourth%29%29" class="RktValLink" data-pltdoc="x">fourth</a></span> exist. <a href="part_two.html#%28counter._%28exercise._ex~3alist-cons5%29%29" class="ex-end" data-pltdoc="x"></a></div></p><h4>11.2<tt> </tt><a name="(part._sec~3acompounding2)"></a>Composing Functions</h4><p><div class="SIntrapara"><a href="part_one.html#%28part._ch~3ahtdp%29" data-pltdoc="x">How to Design Programs</a> explains that programs are collections of definitions:
|
|
structure type definitions, data definitions, constant definitions, and function
|
|
definitions.<span class="refelem"><span class="refcolumn"><span class="refcontent">And don’t forget tests.</span></span></span> To guide the division of
|
|
labor among functions, the section also suggests a rough <a name="(idx._(gentag._290))"></a>guideline:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-style: italic">Design one function per task. Formulate auxiliary function definitions for
|
|
every dependency between quantities in the problem.</span></p></blockquote></div><div class="SIntrapara">This part of the book introduces another guideline on auxiliary functions:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-style: italic">Design one template per data definition.
|
|
Formulate auxiliary function definitions when one data definition points to
|
|
a second data definition.</span></p></blockquote></div></p><p><div class="SIntrapara">In this section, we take a look at one specific place in the <a name="(idx._(gentag._291))"></a>design process
|
|
that may call for additional auxiliary functions: the definition step,
|
|
which creates a full-fledged definition from a template. Turning a template
|
|
into a complete function definition means combining the values of the
|
|
template’s sub-expressions into the final answer. As you do so, you might
|
|
encounter several situations that suggest the need for auxiliary functions:
|
|
</div><div class="SIntrapara"><ol><li><p>If the composition of values requires knowledge of a particular domain of
|
|
application—<wbr></wbr>for example, composing two (computer) images, accounting,
|
|
music, or science—<wbr></wbr>design an auxiliary function.</p></li><li><p>If the composition of values requires a case analysis of the
|
|
available values—<wbr></wbr>for example, depends on a number being positive, zero, or negative—<wbr></wbr>
|
|
use a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression. If the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> looks complex, design
|
|
an auxiliary function whose arguments are the template’s expressions and whose
|
|
body is the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression.</p></li><li><p>If the composition of values must process an element from a
|
|
self-referential data definition—<wbr></wbr>a list, a natural number, or something
|
|
like those—<wbr></wbr>design an auxiliary function.</p></li><li><p>If everything fails, you may need to design a <span style="font-weight: bold">more general</span>
|
|
function and define the main function as a specific use of the general
|
|
function. This suggestion sounds counterintuitive, but it is called for in
|
|
a remarkably large number of cases.</p></li></ol></div></p><p>The last two criteria are situations that we haven’t discussed in any
|
|
detail, though examples have come up before. The next two sections
|
|
illustrate these principles with additional examples.</p><p><div class="SIntrapara">Before we continue, though, remember that the key to managing the
|
|
design of programs is to maintain the often-mentioned
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><span style="font-weight: bold">Wish List</span></p></blockquote></div><div class="SIntrapara"><blockquote><p>Maintain a list of function headers that must be designed to complete a
|
|
program. Writing down complete function headers ensures that you can test
|
|
those portions of the programs that you have finished, which is useful
|
|
even though many tests will fail. Of course, when the wish list is empty,
|
|
all tests should pass and all functions should be covered by tests.</p></blockquote></div><div class="SIntrapara">Before you put a function on the wish list, you should check whether
|
|
something like the function already exists in your language’s teachpack or
|
|
whether something similar is already on the wish list. BSL, BSL+, and
|
|
indeed all programming languages provide many built-in operations and many
|
|
teachpack functions. You should explore your chosen language when you have
|
|
time and when you have a need, so that you know what it provides.</div></p><h4>11.3<tt> </tt><a name="(part._sec~3asort.I)"></a>Auxiliary Functions that Recur</h4><p>People need to sort things all the time, and so do programs. Investment
|
|
advisors sort portfolios by the profit each holding generates. Game
|
|
programs sort lists of players according to scores. And mail programs sort
|
|
messages according to date or sender or some other criterion.</p><p><div class="SIntrapara">In general, you can sort a bunch of items if you can compare and order each
|
|
pair of data items. Although not every kind of data comes with a
|
|
comparison primitive, we all know one that does: numbers. Hence, we use a
|
|
simplistic but highly representative sample problem in this section:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a function that sorts a list of reals.</p></blockquote></div><div class="SIntrapara">The exercises below clarify how to adapt this function to other data.</div></p><p><div class="SIntrapara">Since the problem statement does not mention any other task and since
|
|
sorting does not seem to suggest other tasks, we just follow the design
|
|
recipe. Sorting means rearranging a bunch of numbers. This restatement
|
|
implies a natural data definition for the inputs and outputs of the
|
|
function and thus its signature. Given that we have a definition for
|
|
<a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a>, the first step is easy:<a name="(idx._(gentag._292))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a sorted version of </span><span class="RktSym">alon</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Returning <span class="RktSym">alon</span> ensures that the result is appropriate as far as
|
|
the function signature is concerned, but in general, the given
|
|
list isn’t sorted and this result is wrong.</div></p><p><div class="SIntrapara">When it comes to making up examples, it quickly becomes clear that the
|
|
problem statement is quite imprecise. As before, we use the data
|
|
definition of <a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a> to organize the development of
|
|
examples. Since the data definition consists of two clauses, we need two
|
|
examples. Clearly, when <span class="RktSym">sort></span> is applied to <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, the
|
|
result must be <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. The question is what the result 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">should be. The list isn’t sorted, but there are two ways to sort it:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">12</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>, that is, a
|
|
list with the numbers arranged in <span style="font-weight: bold">descending</span> order; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">12</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>, that is, a
|
|
list with the numbers arranged in <span style="font-weight: bold">ascending</span> order.</p></li></ul></div><div class="SIntrapara">In a real-world situation, you would now have to ask the person who posed
|
|
the problem for clarification. Here we go for the descending alternative;
|
|
designing the ascending alternative doesn’t pose any different obstacles.</div></p><p><div class="SIntrapara">The decision calls for a revision of the header material:<a name="(idx._(gentag._293))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">rearranges </span><span class="RktSym">alon</span><span class="RktCmt"> in descending order</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The header material now includes the <a name="(idx._(gentag._294))"></a>examples reformulated as <a name="(idx._(gentag._295))"></a>unit tests
|
|
and using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span>. If the latter makes you uncomfortable,
|
|
reformulate the test with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> to exercise translating back and
|
|
forth. As for the additional two examples, they demand that <span class="RktSym">sort></span>
|
|
works on lists already sorted in ascending and descending order.</div></p><p><div class="SIntrapara">Next we must translate the data definition into a function template. We
|
|
have dealt with lists of numbers before, so this step is easy:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></p><p><div class="SIntrapara">Using this template, we can finally turn to the interesting part of the
|
|
program development. We consider each case of the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression
|
|
separately, starting with the simple case. If <span class="RktSym">sort></span>’s input is
|
|
<span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, the answer is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, as specified by the example.
|
|
If <span class="RktSym">sort></span>’s input is a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ed list, the template suggests
|
|
two expressions that might help:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> extracts the first number from the input; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">sort></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span> rearranges <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> in
|
|
descending order, according to the purpose statement of the function.</p></li></ul></div><div class="SIntrapara">To clarify these abstract answers, let’s use the second example to
|
|
explain these pieces in detail. When <span class="RktSym">sort></span> consumes <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">12</span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span>,
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is <span class="RktVal">12</span>,</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span>, and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">sort></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span> produces <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span>
|
|
because this list is already sorted.</p></li></ol></div><div class="SIntrapara">To produce the desired answer, <span class="RktSym">sort></span> must insert <span class="RktVal">12</span>
|
|
between the two numbers of the last list. More generally, we must find an
|
|
expression that inserts <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> in its proper place into the
|
|
result of <span class="RktPn">(</span><span class="RktSym">sort></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span>. If we can do so, sorting
|
|
is an easily solved problem.</div></p><p>Inserting a number into a sorted list clearly isn’t a simple task. It
|
|
demands searching through the sorted list to find the proper place of the
|
|
item. Searching through any list demands an auxiliary function
|
|
because lists are of arbitrary size and, by item 3 of the preceding
|
|
section, processing values of arbitrary size calls for the design of an
|
|
auxiliary function.</p><p><div class="SIntrapara">So here is the new wish-list entry: <a name="(idx._(gentag._296))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">inserts </span><span class="RktSym">n</span><span class="RktCmt"> into the sorted list of numbers </span><span class="RktSym">alon</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">That is, <span class="RktSym">insert</span> consumes a number and a list sorted in descending
|
|
order and produces a sorted list by inserting the former into the latter.</div></p><p><div class="SIntrapara">With <span class="RktSym">insert</span>, it is easy to complete the definition of <span class="RktSym">sort></span>:<a name="(idx._(gentag._297))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">In order to produce the final result, <span class="RktSym">sort></span> extracts the first
|
|
item of a non-empty list, computes the sorted version of the rest, and
|
|
uses <span class="RktSym">insert</span> to produce the completely sorted list from the two
|
|
pieces.</div></p><p>Stop! Test the program as is. Some test cases pass, and some fail. That’s
|
|
progress. The next step in its design is the creation of functional
|
|
examples. Since the first input of <span class="RktSym">insert</span> is any number, we use
|
|
<span class="RktVal">5</span> and use the data definition for <a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a> to make
|
|
up examples for the second input.</p><p><div class="SIntrapara">First we consider what <span class="RktSym">insert</span> should produce when given a
|
|
number and <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>. According to <span class="RktSym">insert</span>’s purpose
|
|
statement, the output must be a list, it must contain all numbers from the
|
|
second input, and it must contain the first argument. This suggests the
|
|
following:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">Second, we use a non-empty list of just one item:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The reasoning of why these are the expected results is just like
|
|
before. For one, the result must contain all numbers from the second list
|
|
and the extra number. For two, the result must be sorted.</div></p><p><div class="SIntrapara">Finally, let’s create an example with a list that contains more than one
|
|
item. Indeed, we can derive such an example from the examples for
|
|
<span class="RktSym">sort></span> and especially from our analysis of the second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span>
|
|
clause. From there, we know that <span class="RktSym">sort></span> works only if <span class="RktVal">12</span> is
|
|
inserted into <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">20</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span> at its proper place:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">12</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-5</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">That is, <span class="RktSym">insert</span> is given a second list and it is sorted in
|
|
descending order.</div></p><p>Note what the development of examples teaches us. The <span class="RktSym">insert</span>
|
|
function has to find the first number that is smaller than the given
|
|
<span class="RktSym">n</span>. When there is no such number, the function eventually reaches
|
|
the end of the list and it must add <span class="RktSym">n</span> to the end. Now, before we
|
|
move on to the template, you should work out some additional examples. To
|
|
do so, you may wish to use the supplementary examples for <span class="RktSym">sort></span>.</p><p><div class="SIntrapara">In contrast to <span class="RktSym">sort></span>, the function <span class="RktSym">insert</span> consumes
|
|
<span style="font-weight: bold">two</span> inputs. Since we know that the first one is a number and atomic, we
|
|
can focus on the second argument—<wbr></wbr>the list of numbers—<wbr></wbr>for the template
|
|
development:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 only difference between this template and the one for <span class="RktSym">sort></span> is
|
|
that this one needs to take into account the additional argument <span class="RktSym">n</span>.</div></p><p>To fill the gaps in the template of <span class="RktSym">insert</span>, we again proceed on a
|
|
case-by-case basis. The first case concerns the empty list. According to
|
|
the first example, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="RktPn">)</span> is the expression needed in the first
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause because it constructs a sorted list from <span class="RktSym">n</span>
|
|
and <span class="RktSym">alon</span>.</p><p><div class="SIntrapara">The second case is more complicated than the first, and so we follow the
|
|
questions from <a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">figure <span class="FigureRef">53</span></a>:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is the first number on <span class="RktSym">alon</span>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is the rest of <span class="RktSym">alon</span> and, like
|
|
<span class="RktSym">alon</span>, it is sorted in descending order; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">insert</span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span> produces a sorted list from
|
|
<span class="RktSym">n</span> and the numbers on <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>.</p></li></ol></div><div class="SIntrapara">The problem is how to combine these pieces of data to get the final
|
|
answer.</div></p><p><div class="SIntrapara">Let’s work through some examples to make all this concrete:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">4</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Here <span class="RktSym">n</span> is <span class="RktVal">7</span> and larger than any of the numbers in the
|
|
second input. We know so by just looking at the first item of the list. It
|
|
is <span class="RktVal">6</span>, but because the list is sorted all other numbers on the
|
|
list are even smaller than <span class="RktVal">6</span>. Hence it suffices if we just
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> <span class="RktVal">7</span> onto <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">6</span><span class="stt"> </span><span class="RktVal">5</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>.</div></p><p><div class="SIntrapara">In contrast, when the application is something like
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><span class="RktSym">n</span> must indeed be inserted into the rest of the list. More
|
|
concretely, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is <span class="RktVal">6</span>; <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> is
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span>; and <span class="RktPn">(</span><span class="RktSym">insert</span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span> produces
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span> according to the purpose statement. By adding
|
|
<span class="RktVal">6</span> back onto that last list, we get the desired answer for
|
|
<span class="RktPn">(</span><span class="RktSym">insert</span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">6</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span>.</div></p><p><div class="SIntrapara">To get a complete function definition, we must generalize these
|
|
examples. The case analysis suggests a nested conditional that determines
|
|
whether <span class="RktSym">n</span> is larger than (or equal to) <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>:
|
|
</div><div class="SIntrapara"><ul><li><p>If so, all the items in <span class="RktSym">alon</span> are smaller than <span class="RktSym">n</span>
|
|
because <span class="RktSym">alon</span> is already sorted. The answer in that case is
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>.</p></li><li><p><div class="SIntrapara">If, however, <span class="RktSym">n</span> is smaller than <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>, then
|
|
the function has not yet found the proper place to insert <span class="RktSym">n</span> into
|
|
<span class="RktSym">alon</span>. The first item of the result must be
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span> and <span class="RktSym">n</span> must be inserted into
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span>. The final result in this case 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">because this list contains <span class="RktSym">n</span> and all items of <span class="RktSym">alon</span> in
|
|
sorted order—<wbr></wbr>which is what we need.</div></p></li></ul></div><div class="SIntrapara">The translation of this discussion into BSL+ calls for an
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> expression for such cases. The condition is <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3e~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="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span>, and the expressions for the two branches have been
|
|
formulated.</div></p><p><a href="part_two.html#%28counter._%28figure._fig~3asort%29%29" data-pltdoc="x">Figure <span class="FigureRef">72</span></a> contains the complete sort program. Copy it into the
|
|
definitions area of DrRacket, add the test cases back in, and test the
|
|
program. All tests should pass now, and they should cover all expressions.</p><p><span style="font-weight: bold">Terminology</span> This particular program for sorting is known as
|
|
<span style="font-style: italic">insertion sort</span> in the programming literature. Later we will
|
|
study alternative ways to sort lists, using an entirely different design
|
|
strategy.</p><p><div class="SIntrapara"><a name="(idx._(gentag._298))"></a> <a name="(idx._(gentag._299))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a sorted version of </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">inserts </span><span class="RktSym">n</span><span class="RktCmt"> into the sorted list of numbers </span><span class="RktSym">l</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3e~3d%29%29" class="RktValLink" data-pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3asort))" x-target-lift="Figure"></a>Figure 72: </span>Sorting lists of numbers</span></p></blockquote></div></p><p><a name="(idx._(gentag._300))"></a>
|
|
<a name="(counter._(exercise._ex~3asort0))"></a><span style="font-weight: bold">Exercise</span> 186. Take a second look at <a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a>, the intermezzo
|
|
that presents BSL and its ways of formulating tests. One of the latter
|
|
is <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span>, which determines whether an expression
|
|
satisfies a certain property. Use <span class="RktSym">sorted>?</span> from <a href="part_two.html#%28counter._%28exercise._nelist4%29%29" data-pltdoc="x">exercise 145</a> to
|
|
reformulate the tests for <span class="RktSym">sort></span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span>.</p><p><div class="SIntrapara">Now consider this function definition: <a name="(idx._(gentag._301))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">produces a sorted version of </span><span class="RktSym">l</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sort>/bad</span><span class="hspace"> </span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">9</span><span class="hspace"> </span><span class="RktVal">8</span><span class="hspace"> </span><span class="RktVal">7</span><span class="hspace"> </span><span class="RktVal">6</span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="RktVal">3</span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Can you formulate a test case that shows that <span class="RktSym">sort>/bad</span> is <span style="font-weight: bold">not</span> a
|
|
sorting function? Can you use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> to formulate this
|
|
test case? <a name="(idx._(gentag._302))"></a></div></p><p><span style="font-weight: bold">Notes</span> (1) What may surprise you here is that we define a function to
|
|
create a test. In the real world, this step is common, and, on occasion, you
|
|
really need to design functions for tests—<wbr></wbr>with their own tests and all.
|
|
(2) Formulating tests with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> is occasionally easier
|
|
than using <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span> (or other forms), and it is also a bit
|
|
more general. When the predicate completely describes the relationship
|
|
between all possible inputs and outputs of a function, computer scientists
|
|
speak of a <span style="font-style: italic">specification</span>. <a href="part_three.html#%28part._sec~3aspecification%29" data-pltdoc="x">Specifying with <span class="RktSym"><span class="RktStxLink">lambda</span></span></a> explains how
|
|
to specify <span class="RktSym">sort></span> completely. <a href="part_two.html#%28counter._%28exercise._ex~3asort0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asort1-b))"></a><span style="font-weight: bold">Exercise</span> 187. Design a program that sorts lists of game players by score:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">gp</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">score</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._gameplayer)"></a><span style="font-style: italic">GamePlayer</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-gp</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-gp</span><span class="stt"> </span><span class="RktSym">p</span><span class="stt"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktCmt"> represents player </span><span class="RktSym">p</span><span class="RktCmt"> who </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">scored a maximum of </span><span class="RktSym">s</span><span class="RktCmt"> points </span></td></tr></table></blockquote></div><div class="SIntrapara"><span style="font-weight: bold">Hint</span> Formulate a function that compares two elements of <a href="part_two.html#%28tech._gameplayer%29" class="techoutside" data-pltdoc="x"><span class="techinside">GamePlayer</span></a>. <a href="part_two.html#%28counter._%28exercise._ex~3asort1-b%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asort1))"></a><span style="font-weight: bold">Exercise</span> 188. Design a program that sorts lists of emails by date:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">email</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">from</span><span class="hspace"> </span><span class="RktSym">date</span><span class="hspace"> </span><span class="RktSym">message</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._email._message)"></a><span style="font-style: italic">Email Message</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-email</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-email</span><span class="stt"> </span><span class="RktSym">f</span><span class="stt"> </span><span class="RktSym">d</span><span class="stt"> </span><span class="RktSym">m</span><span class="RktPn">)</span><span class="RktCmt"> represents text </span><span class="RktSym">m</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">sent by </span><span class="RktSym">f</span><span class="RktCmt">, </span><span class="RktSym">d</span><span class="RktCmt"> seconds after the beginning of time </span></td></tr></table></blockquote></div><div class="SIntrapara">Also develop a program that sorts lists of email messages by name. To
|
|
compare two strings alphabetically, use the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._string~3c~3f%29%29" class="RktValLink" data-pltdoc="x">string<?</a></span> primitive. <a href="part_two.html#%28counter._%28exercise._ex~3asort1%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3asort2))"></a><span style="font-weight: bold">Exercise</span> 189. Here is the function <span class="RktSym">search</span>:<a name="(idx._(gentag._303))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-numbers</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">search</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">search</span><span class="hspace"> </span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">alon</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">It determines whether some number occurs in a list of numbers. The function
|
|
may have to traverse the entire list to find out that the number of
|
|
interest isn’t contained in the list.</div></p><p>Develop the function <span class="RktSym">search-sorted</span>, which determines whether a
|
|
number occurs in a sorted list of numbers. The function must take advantage
|
|
of the fact that the list is sorted. <a href="part_two.html#%28counter._%28exercise._ex~3asort2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aprefix-bsl))"></a><span style="font-weight: bold">Exercise</span> 190. Design the <span class="RktSym">prefixes</span> function, which consumes
|
|
a list of <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s and produces the list of all prefixes. A list
|
|
<span class="RktSym">p</span> is a <span style="font-style: italic">prefix</span> of <span class="RktSym">l</span> if <span class="RktSym">p</span> and
|
|
<span class="RktSym">l</span> are the same up through all items in <span class="RktSym">p</span>. For example,
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </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="RktPn">)</span> is a prefix of itself and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </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="stt"> </span><span class="RktVal">"d"</span><span class="RktPn">)</span>.</p><p>Design the function <span class="RktSym">suffixes</span>, which consumes a list of
|
|
<a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s and produces all <span class="RktSym">suffixes</span>. A list <span class="RktSym">s</span> is a
|
|
<span style="font-style: italic">suffix</span> of <span class="RktSym">l</span> if <span class="RktSym">s</span> and <span class="RktSym">l</span> are the same from the
|
|
end, up through all items in <span class="RktSym">s</span>. For example, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"b"</span><span class="stt"> </span><span class="RktVal">"c"</span><span class="stt"> </span><span class="RktVal">"d"</span><span class="RktPn">)</span> is a
|
|
suffix of itself and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </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="stt"> </span><span class="RktVal">"d"</span><span class="RktPn">)</span>. <a href="part_two.html#%28counter._%28exercise._ex~3aprefix-bsl%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>11.4<tt> </tt><a name="(part._sec~3agen-funcs)"></a>Auxiliary Functions that Generalize</h4><p>On occasion an auxiliary function is not just a small helper function but a
|
|
solution to a more general problem. Such auxiliaries are needed when a
|
|
problem statement is too narrow. As programmers work through the steps of
|
|
the design recipe, they may discover that the “natural” solution is
|
|
wrong. An analysis of this broken solution may suggest a slightly
|
|
different, but more general, problem statement, as well as a simple way of using
|
|
the solution to the general problem for the original one.</p><p><div class="SIntrapara">We illustrate this idea with a solution to the following problem:<span class="refelem"><span class="refcolumn"><span class="refcontent">Paul C. Fisher suggested this problem.</span></span></span>
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a function that adds a polygon to a given scene.</p></blockquote></div><div class="SIntrapara">Just in case you don’t recall your basic geometry (domain) knowledge, we
|
|
add a (simplistic) definition of polygon:
|
|
</div><div class="SIntrapara"><blockquote><p>A <span style="font-style: italic">polygon</span> is a planar figure with at least three points (not on
|
|
a straight line) connected by three straight sides.</p></blockquote></div></p><p><div class="SIntrapara">One natural data representation for a polygon is thus a list of
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. For example, the following two definitions
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">triangle-p</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">30</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td valign="top"><p><span class="hspace"> </span></p></td><td valign="top"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">square-p</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">introduce a triangle and a square, just as the names say. Now you may
|
|
wonder how to interpret <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> or <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">30</span><span class="stt"> </span><span class="RktVal">40</span><span class="RktPn">)</span><span class="RktPn">)</span>
|
|
as polygons, and the answer is that they do <span style="font-weight: bold">not</span> describe
|
|
polygons. Because a polygon consists of at least three points,
|
|
a good data representation of polygons is the collection of lists with at
|
|
least three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s.</div></p><p><div class="SIntrapara">Following the development of the data definition for non-empty lists of
|
|
temperatures (<a href="part_two.html#%28tech._nelist._of._temperature%29" class="techoutside" data-pltdoc="x"><span class="techinside">NEList-of-temperatures</span></a>, in <a href="part_two.html#%28part._sec~3alists~3ane%29" data-pltdoc="x">Non-empty Lists</a>),
|
|
formulating a data representation for polygons 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"> </span><span class="RktCmt">A </span><a name="(tech._polygon)"></a><span style="font-style: italic">Polygon</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first clause says that a list of three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s is a
|
|
<a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>, and the second clause says that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span>ing a
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> onto some existing <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> creates another one. Since
|
|
this data definition is the very first to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> in one of its
|
|
clauses, we spell it out with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> just to make sure you see this
|
|
conversion from an abbreviation to long-hand in this context:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">a </span><span style="font-style: italic">Polygon</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</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="RktPn">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>The point is that a naively chosen data representation—<wbr></wbr>plain lists of
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s—<wbr></wbr>may not properly represent the intended
|
|
information. Revising the data definition during an initial exploration is
|
|
normal; indeed, on occasion such revisions become necessary during the rest
|
|
of the design process. As long as you stick to a systematic approach,
|
|
though, changes to the data definition can naturally be propagated through
|
|
the rest of the design.</p><p><div class="SIntrapara">The second step calls for the signature, purpose statement, and header of the
|
|
function. Since the problem statement mentions just one task and no other task is
|
|
implied, we start with one function: <a name="(idx._(gentag._304))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">a plain background image </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._empty-scene%29%29" class="RktValLink" data-pltdoc="x">empty-scene</a></span><span class="hspace"> </span><span class="RktVal">50</span><span class="hspace"> </span><span class="RktVal">50</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders the given polygon </span><span class="RktSym">p</span><span class="RktCmt"> into </span><span class="RktSym">img</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">img</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The additional definition of <span class="RktSym">MT</span> is called for because it
|
|
simplifies the formulation of examples.</div></p><p><div class="SIntrapara">For the first example, we use the above-mentioned triangle. A quick look in
|
|
<span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/image</span></span> teachpack</span> suggests <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span> is the function
|
|
needed to render the three lines for a triangle:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktSym">triangle-p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">30</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">30</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The innermost<span class="refelem"><span class="refcolumn"><span class="refcontent">Of course, we experimented in DrRacket’s interactions area to
|
|
get this expression right.</span></span></span> <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span> renders the line from the first to the second
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>; the middle one uses the second and third <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>; and
|
|
the outermost <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span> connects the third and the first
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p><p><div class="SIntrapara">Given that the first and smallest polygon is a triangle, then a rectangle or a
|
|
square suggests itself as the second example. We use <span class="RktSym">square-p</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktSym">square-p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">A square is just one more point than a triangle, and it is easy to
|
|
render. You may also wish to draw these shapes on a piece of graph paper.</div></p><p><div class="SIntrapara">The construction of the template poses a challenge. Specifically,
|
|
the first and the second questions of <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure <span class="FigureRef">52</span></a> ask whether
|
|
the data definition differentiates distinct subsets and how to distinguish
|
|
among them. While the data definition clearly sets apart triangles from
|
|
all other polygons in the first clause, it is not immediately clear how to
|
|
differentiate the two. Both clauses describe lists of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. The
|
|
first describes lists of three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, while the second one describes
|
|
lists of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s that have at least four items. Thus one
|
|
alternative is to ask whether the given polygon is three items long:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Using the long-hand version of the first clause, that 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">suggests a second way to formulate the first condition, namely, checking whether
|
|
the given <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> is empty after using three <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> functions:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Since all <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>s consist of at least three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, using
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> three times is legal. Unlike <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span>, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span>
|
|
is a primitive, easy-to-understand operation with a clear operational
|
|
meaning. It selects the second field in a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> structure and that
|
|
is all it does.</div></p><p><span class="refelem"><span class="refcolumn"><span class="refcontent">It is truly better to formulate conditions in terms of built-in
|
|
predicates and selectors than your own (recursive) functions. See
|
|
<a href="i5-6.html" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a> for an explanation.</span></span></span></p><p><div class="SIntrapara">The rest of the questions in <a href="part_two.html#%28counter._%28figure._fig~3atemplate-q%29%29" data-pltdoc="x">figure <span class="FigureRef">52</span></a> have direct answers,
|
|
and thus we get this 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Because <span class="RktSym">p</span> describes a triangle in the first clause,
|
|
it must consist of exactly three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, which are extracted via
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span>, and <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span>. In the second clause,
|
|
<span class="RktSym">p</span> consists of a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and a
|
|
<span class="RktSym">Polygon</span>, justifying <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>.
|
|
The former extracts a <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> from <span class="RktSym">p</span>, the latter a
|
|
<span class="RktSym">Polygon</span>. We therefore add a self-referential function call around
|
|
it; we must also keep in mind that dealing with <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> in
|
|
this clause and the three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s in the first clause may
|
|
demand the design of an auxiliary function.</div></p><p><div class="SIntrapara">Now we are ready to focus on the function definition, dealing with one
|
|
clause at a time. The first clause concerns triangles, which
|
|
suggests a straightforward answer. Specifically, there are
|
|
three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s and <span class="RktSym">render-poly</span> should connect the three in
|
|
an empty scene of 50 by 50 pixels. Given that <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> is a separate data
|
|
definition, we get an obvious wish-list entry: <a name="(idx._(gentag._305))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">draws a red line from </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><span class="RktSym">p</span><span class="RktCmt"> to </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><span class="RktSym">q</span><span class="RktCmt"> into </span><span class="RktSym">im</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktSym">im</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">im</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Using this function, the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause in
|
|
<span class="RktSym">render-poly</span> is this:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">render-line</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This expression obviously renders the given <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> <span class="RktSym">p</span> as a
|
|
triangle by drawing a line from the first to the second, the second to the
|
|
third, and the third to the first <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p><p><div class="SIntrapara">The second <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause is about <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>s that have been
|
|
extended with one <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>. In the template, we find two expressions,
|
|
and, following <a href="part_two.html#%28counter._%28figure._fig~3adefinition-q%29%29" data-pltdoc="x">figure <span class="FigureRef">53</span></a>, we remind ourselves of what
|
|
these expressions compute:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> extracts the first <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> extracts the <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> from <span class="RktSym">p</span>; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="stt"> </span><span class="RktSym">img</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span> renders <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>,
|
|
which is what the purpose statement of the function says.</p></li></ol></div><div class="SIntrapara">The question is how to use these pieces to render the given
|
|
<a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> <span class="RktSym">p</span>.</div></p><p><div class="SIntrapara">One idea that may come to mind is that <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> consists of at
|
|
least three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s. It is therefore possible to extract at least
|
|
one <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> from this embedded <span class="RktSym">Polygon</span> and to connect
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> with this additional point. Here is what this idea looks
|
|
like with BSL+ code:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="stt"> </span><span class="RktSym">MT</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">As mentioned, the highlighted sub-expression renders the embedded
|
|
<a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> in an empty 50 by 50 scene. The use of <span class="RktSym">render-line</span>
|
|
adds one line to this scene, from the first to the second <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> of
|
|
<span class="RktSym">p</span>.</div></p><p><div class="SIntrapara">Our analysis suggests a rather natural, complete function definition:
|
|
<a name="(idx._(gentag._306))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Designing <span class="RktSym">render-line</span> is the kind of problem that you solved in the first
|
|
part of the book. Hence we just provide the final definition so that you can
|
|
test the above function: <a name="(idx._(gentag._307))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders a line from </span><span class="RktSym">p</span><span class="RktCmt"> to </span><span class="RktSym">q</span><span class="RktCmt"> into </span><span class="RktSym">img</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">img</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Develop a test for <span class="RktSym">render-line</span>.</div></p><p>Lastly, we must test the functions. The tests for
|
|
<span class="RktSym">render-poly</span> fail. On the one hand, the test failure is fortunate
|
|
because it is the purpose of tests to find problems before they affect
|
|
regular consumers. On the other hand, the flaw is unfortunate because we
|
|
followed the design recipe, we made fairly natural choices, and yet the
|
|
function doesn’t work.</p><p><div class="SIntrapara">Stop! Why do you think the tests fail? Draw an image of the pieces in the
|
|
template of <span class="RktSym">render-poly</span>. Then draw the line that combines
|
|
them. Alternatively, experiment in DrRacket’s interactions area:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktSym">square-p</span><span class="RktPn">)</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_102.png" alt="image" width="57" height="57"/></p></td></tr></table></blockquote></div><div class="SIntrapara">The image shows that <span class="RktSym">render-poly</span> connects the three dots of
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> and then connects <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> to the first point
|
|
of <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>, that is, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>. You can easily
|
|
validate this claim with an interaction that uses <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">square-p</span><span class="RktPn">)</span>
|
|
directly as input for <span class="RktSym">render-poly</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">square-p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_103.png" alt="image" width="57" height="57"/></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara">In addition, you may wonder what <span class="RktSym">render-poly</span> would draw if we added
|
|
another point, say, <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="stt"> </span><span class="RktVal">40</span><span class="stt"> </span><span class="RktVal">30</span><span class="RktPn">)</span>, to the original square:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktSym">MT</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">40</span><span class="hspace"> </span><span class="RktVal">30</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">square-p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_104.png" alt="image" width="57" height="57"/></p></td></tr></table></blockquote></div><div class="SIntrapara">Instead of the desired pentagon, <span class="RktSym">render-poly</span> always draws the
|
|
triangle at the end of the given <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> and otherwise connects the
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s that precede the triangle.</div></p><p>While the experiments confirm the problems of our design, they also suggest
|
|
that the function is “almost correct.” It connects the successive dots
|
|
specified by a list of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s, and then it draws a line from the first
|
|
to the last <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> of the trailing triangle. If it skipped this last
|
|
step, the function would just “connect the dots” and thus draw an “open”
|
|
polygon. By connecting the first and the last point, it could then complete
|
|
its task.</p><p><div class="SIntrapara">Put differently, the analysis of our failure suggests a two-step solution:
|
|
</div><div class="SIntrapara"><ol><li><p>Solve a <span style="font-weight: bold">more general</span> problem.</p></li><li><p>Use the solution to this general problem to solve the original one.</p></li></ol></div><div class="SIntrapara">We start with the statement for the general problem:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a function that draws connections between a given
|
|
bunch of dots and into a given scene.</p></blockquote></div></p><p><div class="SIntrapara">Although the design of <span class="RktSym">render-poly</span> almost solves this problem, we
|
|
design this function mostly from scratch. First, we need a data
|
|
definition. Connecting the dots makes no sense unless we have at least a
|
|
couple of dots. To keep things simple, we go with at least one dot:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._nelop)"></a><span style="font-style: italic">NELoP</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="stt"> </span><a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Second, we formulate a signature, a purpose statement, and a header for a
|
|
“connect the dots” function:<a name="(idx._(gentag._308))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">connects the dots in </span><span class="RktSym">p</span><span class="RktCmt"> by rendering lines in </span><span class="RktSym">img</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">MT</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Third, we adapt the examples for <span class="RktSym">render-poly</span> for this new
|
|
function. As our failure analysis says, the function connects the first
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> on <span class="RktSym">p</span> to the second one, the second one to the
|
|
third, the third to the fourth, and so on, all the way to the last one,
|
|
which isn’t connected to anything. Here is the adaptation of the first
|
|
example, a list of three <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktSym">triangle-p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span><span class="hspace"> </span><span class="RktSym">MT</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">30</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">20</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The expected value is an image with two lines: one from the first
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> to the second one, and another one from the second to the third
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>.</div></p><p><a name="(counter._(exercise._connect-dots-ex))"></a><span style="font-weight: bold">Exercise</span> 191. Adapt the second example for the
|
|
<span class="RktSym">render-poly</span> function to <span class="RktSym">connect-dots</span>. <a href="part_two.html#%28counter._%28exercise._connect-dots-ex%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Fourth, we use the template for functions that process non-empty 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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 template has two clauses: one for lists of one <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> and the
|
|
second one for lists with more than one. Since there is at least one
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> in both cases, the template contains <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> in
|
|
both clauses; the second one also contains <span class="RktPn">(</span><span class="RktSym">connects-dots</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span> to remind us of the self-reference in the second clause of the data
|
|
definition.</div></p><p><div class="SIntrapara">The fifth and central step is to turn the template into a function
|
|
definition. Since the first clause is the simplest one, we start with
|
|
it. As we have already said, it is impossible to connect anything when the
|
|
given list contains only one <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>. Hence, the function just
|
|
returns <span class="RktSym">MT</span> from the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause. For the second
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clause, let us remind ourselves of what the template
|
|
expressions compute:
|
|
</div><div class="SIntrapara"><ol><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> extracts the first <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>;</p></li><li><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> extracts the <a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a> from <span class="RktSym">p</span>; and</p></li><li><p><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="stt"> </span><span class="RktSym">img</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span> connects the dots in
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span> by rendering lines in <span class="RktSym">img</span>.</p></li></ol></div><div class="SIntrapara">From our first attempt to design <span class="RktSym">render-poly</span>, we know
|
|
<span class="RktSym">connect-dots</span> needs to add one line to the result of
|
|
<span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="stt"> </span><span class="RktSym">img</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span>, namely, from <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>
|
|
to <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="stt"> </span><span class="RktSym">p</span><span class="RktPn">)</span>. We know that <span class="RktSym">p</span> contains a second
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> because otherwise the evaluation of <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> would have
|
|
picked the first clause.</div></p><p><div class="SIntrapara">Putting everything together, we get the following definition:
|
|
<a name="(idx._(gentag._309))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">img</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">This definition looks simpler than the faulty version of
|
|
<span class="RktSym">render-poly</span>, even though it copes with two more lists of
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s than <span class="RktSym">render-poly</span>.<span class="refelem"><span class="refcolumn"><span class="refcontent">This argument is
|
|
<span style="font-weight: bold">informal</span>. If you ever need a <span style="font-weight: bold">formal</span> argument for such claims
|
|
about the relationship between sets or functions, you will need to study
|
|
<span style="font-style: italic">logic</span>. Indeed, this book’s design process is deeply informed by
|
|
logic, and a course on logic in computation is a natural complement. In
|
|
general, logic is to computing what analysis is to engineering.</span></span></span></div></p><p>Conversely, we say that <span class="RktSym">connect-dots</span> generalizes <span class="RktSym">render-poly</span>.
|
|
Every input for the latter is also an input for the former. Or in terms of
|
|
data definitions, every <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a> is also an <a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a>. But, there are
|
|
many <a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a>s that are <span style="font-weight: bold">not</span> <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>s. To be precise, all
|
|
lists of <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s that contain two items or one belong to <a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a> but
|
|
not to <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>. The key insight for you is, however, that just because
|
|
a function has to deal with more inputs than another function does <span style="font-weight: bold">not</span>
|
|
mean that the former is more complex than the latter; generalizations often
|
|
simplify function definitions.</p><p><div class="SIntrapara">As spelled out above, <span class="RktSym">render-poly</span> can use
|
|
<span class="RktSym">connect-dots</span> to connect all successive <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a>s of the given
|
|
<a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>; to complete its task, it must then add a line from the
|
|
first to the last <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> of the given <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>. In terms of
|
|
code, this just means composing two functions: <span class="RktSym">connect-dots</span> and
|
|
<span class="RktSym">render-line</span>, but we also need a function to extract the last
|
|
<a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> from the <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>. Once we are granted this wish, the
|
|
definition of <span class="RktSym">render-poly</span> is a one-liner:<a name="(idx._(gentag._310))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds an image of </span><span class="RktSym">p</span><span class="RktCmt"> to </span><span class="RktSym">img</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Formulating the wish-list entry for <span class="RktSym">last</span> 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"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">extracts the last item from </span><span class="RktSym">p</span></td></tr></table></blockquote></div><div class="SIntrapara">Then again, it is clear that <span class="RktSym">last</span> could be a generally useful
|
|
function and we might be better off designing it for inputs from <a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a>: <a name="(idx._(gentag._311))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">extracts the last item from </span><span class="RktSym">p</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Why is it acceptable to use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span> for the stub definition of
|
|
<span class="RktSym">last</span>?</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._render-poly-last))"></a><span style="font-weight: bold">Exercise</span> 192. Argue why it is acceptable to use <span class="RktSym">last</span>
|
|
on <a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>s. Also argue why you may adapt the template for
|
|
<span class="RktSym">connect-dots</span> to <span class="RktSym">last</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Finally, develop examples for <span class="RktSym">last</span>, turn them into tests, and
|
|
ensure that the definition of <span class="RktSym">last</span> in <a href="part_two.html#%28counter._%28figure._fig~3adraw-poly%29%29" data-pltdoc="x">figure <span class="FigureRef">73</span></a>
|
|
works on your examples. <a href="part_two.html#%28counter._%28exercise._render-poly-last%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><div class="SIntrapara"><a name="(idx._(gentag._312))"></a> <a name="(idx._(gentag._313))"></a> <a name="(idx._(gentag._314))"></a> <a name="(idx._(gentag._315))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">adds a corner of </span><span class="RktSym">p</span><span class="RktCmt"> to </span><span class="RktSym">img</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-poly</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._nelop%29" class="techoutside" data-pltdoc="x"><span class="techinside">NELoP</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">connects the </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt">s in </span><span class="RktSym">p</span><span class="RktCmt"> in an image</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">img</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">connect-dots</span><span class="hspace"> </span><span class="RktSym">img</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">draws a red line from </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><span class="RktSym">p</span><span class="RktCmt"> to </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><span class="RktSym">q</span><span class="RktCmt"> into </span><span class="RktSym">im</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-line</span><span class="hspace"> </span><span class="RktSym">im</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._scene%2Bline%29%29" class="RktValLink" data-pltdoc="x">scene+line</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">im</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">q</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">extracts the last item from </span><span class="RktSym">p</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._third%29%29" class="RktValLink" data-pltdoc="x">third</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">last</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3adraw-poly))" x-target-lift="Figure"></a>Figure 73: </span>Drawing a polygon</span></p></blockquote></div></p><p>In summary, the development of <span class="RktSym">render-poly</span> naturally points us to
|
|
consider the general problem of connecting a list of successive dots. We
|
|
can then solve the original problem by defining a function that composes
|
|
the general function with other auxiliary functions. The program therefore
|
|
consists of a relatively straightforward main
|
|
function—<wbr></wbr><span class="RktSym">render-poly</span>—<wbr></wbr>and complex auxiliary functions that
|
|
perform most of the work. You will see time and again that this kind of
|
|
design approach is common and a good method for designing and organizing
|
|
programs.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3adraw-poly0))"></a><span style="font-weight: bold">Exercise</span> 193. Here are two more ideas for defining
|
|
<span class="RktSym">render-poly</span>:
|
|
</div><div class="SIntrapara"><ul><li><p><span class="RktSym">render-poly</span> could <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span> the last item of
|
|
<span class="RktSym">p</span> onto <span class="RktSym">p</span> and then call <span class="RktSym">connect-dots</span>.</p></li><li><p><span class="RktSym">render-poly</span> could add the first item of <span class="RktSym">p</span> to the
|
|
end of <span class="RktSym">p</span> via a version of <span class="RktSym">add-at-end</span> that works on
|
|
<a href="part_two.html#%28tech._polygon%29" class="techoutside" data-pltdoc="x"><span class="techinside">Polygon</span></a>s.</p></li></ul></div><div class="SIntrapara">Use both ideas to define <span class="RktSym">render-poly</span>; make sure both definitions
|
|
pass the test cases. <a href="part_two.html#%28counter._%28exercise._ex~3adraw-poly0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3adraw-poly1))"></a><span style="font-weight: bold">Exercise</span> 194. Modify <span class="RktSym">connect-dots</span> so that it consumes
|
|
an additional <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> to which the last <a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a> is connected. Then
|
|
modify <span class="RktSym">render-poly</span> to use this new version of
|
|
<span class="RktSym">connect-dots</span>. <a href="part_two.html#%28counter._%28exercise._ex~3adraw-poly1%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Naturally, functions such as <span class="RktSym">last</span> are available in a full-fledged
|
|
programming language, and something like <span class="RktSym">render-poly</span> is available
|
|
in <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/image</span></span> teachpack</span>. If you are wondering why we just designed these
|
|
functions, consider the titles of both the book and this section. The goal is
|
|
<span style="font-weight: bold">not</span> (just) to design useful functions but to study how code is designed
|
|
systematically. Specifically, this section is about the idea of
|
|
generalization in the design process; for more on this idea see
|
|
<a href="part_three.html" data-pltdoc="x">Abstraction</a> and <a href="part_six.html" data-pltdoc="x">Accumulators</a>.</p><h3>12<tt> </tt><a name="(part._ch~3aproj-lists)"></a>Projects: Lists</h3><p>This chapter presents several extended exercises, all of which aim to
|
|
solidify your understanding of the elements of design: the design of
|
|
batch<span class="refelem"><span class="refcolumn"><span class="refcontent">This chapter relies on <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/batch-io</span></span> teachpack</span>.</span></span></span> and
|
|
interactive programs, design by composition, design wish lists, and the
|
|
design recipe for functions. The first section covers problems involving
|
|
real-world data: English dictionaries and iTunes libraries. A word-games
|
|
problem requires two sections: one to illustrate design by composition,
|
|
the other to tackle the heart of the problem. The remaining sections are
|
|
about games and finite-state machines.</p><h4>12.1<tt> </tt><a name="(part._sec~3adict)"></a>Real-World Data: Dictionaries</h4><p>Information in the real world tends to come in large quantities, which is
|
|
why it makes so much sense to use programs for processing it. For example,
|
|
a dictionary does not just contain a dozen words, but hundreds of
|
|
thousands. When you want to process such large pieces of information, you
|
|
must carefully design the program using small examples. Once
|
|
you<span class="refelem"><span class="refcolumn"><span class="refcontent">For performance concerns, see <a href="part_five.html" data-pltdoc="x">Generative Recursion</a>. From
|
|
here to there, the focus is on designing programs systematically so that
|
|
you can then explore performance problems properly.</span></span></span> have convinced
|
|
yourself that the programs work properly, you run them on the real-world
|
|
data to get real results. If the program is too slow to process this large
|
|
quantity of data, reflect on each function and how it works. Question
|
|
whether you can eliminate any redundant computations.</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"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">LOCATION</span><span class="hspace"> </span><span class="RktVal">"/usr/share/dict/words"</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">On LINUX: /usr/share/dict/words or /var/lib/dict/words</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">On WINDOWS: borrow the word file from your Linux friend</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._dictionary)"></a><span style="font-style: italic">Dictionary</span><span class="RktCmt"> is a </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">AS-LIST</span><span class="hspace"> </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"> </span><span class="RktSym">LOCATION</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3areading-a-dictionary))" x-target-lift="Figure"></a>Figure 74: </span>Reading a dictionary</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3areading-a-dictionary%29%29" data-pltdoc="x">Figure <span class="FigureRef">74</span></a> displays the one line of code needed
|
|
to read in an entire dictionary of the English language. To get an idea of
|
|
how large such dictionaries are, adapt the code from the figure for your
|
|
particular computer and use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._length%29%29" class="RktValLink" data-pltdoc="x">length</a></span> to determine how many words
|
|
are in your dictionary. There are 235,886 words in ours today, July 25,
|
|
2017.</p><p><div class="SIntrapara">In the following exercises, letters play an important role. You may wish to
|
|
add the following to the top of your program in addition to your adaptation
|
|
of <a href="part_two.html#%28counter._%28figure._fig~3areading-a-dictionary%29%29" data-pltdoc="x">figure <span class="FigureRef">74</span></a>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._letter)"></a><span style="font-style: italic">Letter</span><span class="RktCmt"> is one of the following </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">s: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">"a"</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> ... </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">"z"</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">or, equivalently, a </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="RktCmt"> of this list: </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">LETTERS</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._explode%29%29" class="RktValLink" data-pltdoc="x">explode</a></span><span class="hspace"> </span><span class="RktVal">"abcdefghijklmnopqrstuvwxyz"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><span style="font-weight: bold">Hint</span> Use <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span> to formulate examples and tests for the exercises.</div></p><p><a name="(counter._(exercise._ex~3adictionary1))"></a><span style="font-weight: bold">Exercise</span> 195. Design the function <span class="RktSym">starts-with#</span>, which
|
|
consumes a <a href="part_two.html#%28tech._letter%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter</span></a> and <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> and then counts how many
|
|
words in the given <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> start with the given <a href="part_two.html#%28tech._letter%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter</span></a>.
|
|
Once you know that your function works, determine how many words start
|
|
with <span class="RktVal">"e"</span> in your computer’s dictionary and how many with
|
|
<span class="RktVal">"z"</span>. <a href="part_two.html#%28counter._%28exercise._ex~3adictionary1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adictionary2))"></a><span style="font-weight: bold">Exercise</span> 196. Design <span class="RktSym">count-by-letter</span>. The function
|
|
consumes a <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> and counts how often each letter is used as
|
|
the first one of a word in the given dictionary. Its result is a list of
|
|
<a name="(tech._letter._count)"></a><span style="font-style: italic">Letter-Count</span>s, a piece of data that combines letters and counts.</p><p>Once your function is designed, determine how many words appear for all
|
|
letters in your computer’s dictionary.</p><p><span style="font-weight: bold">Note on Design Choices</span> An alternative is to design an auxiliary
|
|
function that consumes a list of letters and a dictionary and produces a
|
|
list of <a href="part_two.html#%28tech._letter._count%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter-Count</span></a>s that report how often the given letters occur
|
|
as first ones in the dictionary. You may of course reuse your solution of
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3adictionary1%29%29" data-pltdoc="x">exercise 195</a>. <span style="font-weight: bold">Hint</span> If you design this variant, notice
|
|
that the function consumes two lists, requiring a design problem that is
|
|
covered in <a href="part_four.html#%28part._ch~3asimu%29" data-pltdoc="x">Simultaneous Processing</a> in detail. Think of <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> as an
|
|
atomic piece of data that is along for the ride and is handed over to
|
|
<span class="RktSym">starts-with#</span> as needed. <a href="part_two.html#%28counter._%28exercise._ex~3adictionary2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3adictionary3))"></a><span style="font-weight: bold">Exercise</span> 197. Design <span class="RktSym">most-frequent</span>. The function
|
|
consumes a <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a>. It produces the <a href="part_two.html#%28tech._letter._count%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter-Count</span></a> for the
|
|
letter that occurs most often as the first one in the given
|
|
<a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a>.</p><p>What is the most frequently used letter in your computer’s dictionary and
|
|
how often is it used?</p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Design Choices</span> This exercise calls for the composition of
|
|
the solution to the preceding exercise with a function that picks the
|
|
correct pairing from a list of <a href="part_two.html#%28tech._letter._count%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter-Count</span></a>s. There are two ways to
|
|
design this latter function:
|
|
</div><div class="SIntrapara"><ul><li><p>Design a function that picks the pair with the maximum count.</p></li><li><p>Design a function that selects the first from a sorted list of pairs.</p></li></ul></div><div class="SIntrapara">Consider designing both. Which one do you prefer? Why? <a href="part_two.html#%28counter._%28exercise._ex~3adictionary3%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3adictionary4))"></a><span style="font-weight: bold">Exercise</span> 198. Design <span class="RktSym">words-by-first-letter</span>. The
|
|
function consumes a <a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a> and produces a list of
|
|
<a href="part_two.html#%28tech._dictionary%29" class="techoutside" data-pltdoc="x"><span class="techinside">Dictionary</span></a>s, one per <a href="part_two.html#%28tech._letter%29" class="techoutside" data-pltdoc="x"><span class="techinside">Letter</span></a>.</p><p><div class="SIntrapara">Redesign <span class="RktSym">most-frequent</span> from <a href="part_two.html#%28counter._%28exercise._ex~3adictionary3%29%29" data-pltdoc="x">exercise 197</a> using this new
|
|
function. Call the new function <span class="RktSym">most-frequent.v2</span>. Once you have
|
|
completed the design, ensure that the two functions compute the same
|
|
result on your computer’s dictionary:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">most-frequent</span><span class="hspace"> </span><span class="RktSym">AS-LIST</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">most-frequent.v2</span><span class="hspace"> </span><span class="RktSym">AS-LIST</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Design Choices</span> For <span class="RktSym">words-by-first-letter</span> you have
|
|
a choice for dealing with the situation when the given dictionary does not
|
|
contain any words for some letter:
|
|
</div><div class="SIntrapara"><ul><li><p>One alternative is to exclude the resulting empty dictionaries from
|
|
the overall result. Doing so simplifies both the testing of the function
|
|
and the design of <span class="RktSym">most-frequent.v2</span>, but it also requires the
|
|
design of an auxiliary function.</p></li><li><p>The other one is to include <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> as the result of looking for
|
|
words of a certain letter, even if there aren’t any. This alternative
|
|
avoids the auxiliary function needed for the first alternative but
|
|
adds complexity to the design of <span class="RktSym">most-frequent.v2</span>. <span style="font-weight: bold">End</span></p></li></ul></div></p><p><span style="font-weight: bold">Note on Intermediate Data and Deforestation</span> This second version of
|
|
the word-counting function computes the desired result via the creation of
|
|
a large intermediate data structure that serves no real purpose other than
|
|
that its parts are counted. On occasion, the programming language
|
|
eliminates them automatically by <span style="font-style: italic">fusing</span> the two functions into
|
|
one, a transformation on programs that is also called
|
|
<span style="font-style: italic">deforestation</span>. When you know that the language does not deforest
|
|
programs, consider eliminating such data structures if the program does
|
|
not process data fast enough. <a href="part_two.html#%28counter._%28exercise._ex~3adictionary4%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>12.2<tt> </tt><a name="(part._itunes-data._sec~3aitunes)"></a>Real-World Data: iTunes</h4><p>Apple’s iTunes software is widely used to collect music, videos, TV shows,
|
|
and so on. You may wish to analyze the information that your iTunes
|
|
application gathers. It is actually quite easy to extract its
|
|
database. Select the application’s <span class="stt">File</span> menu, choose <span class="stt">Library</span> and
|
|
then <span class="stt">Export</span>—<wbr></wbr>and voilà, you can export a so-called XML representation
|
|
of the iTunes information.<span class="refelem"><span class="refcolumn"><span class="refcontent">Since such proprietary formats
|
|
change regularly, the book comes with two sample files:
|
|
<a href="Https://felleisen.org/matthias/HtDP2e/Files/itunes.xml">itunes.xml</a>
|
|
and
|
|
<a href="Https://felleisen.org/matthias/HtDP2e/Files/itunes.xml">itunes2.xml</a>.
|
|
You may wish to use those instead of your own.</span></span></span>
|
|
Processing XML is covered in some depth by
|
|
<a href="part_four.html#%28part._ch~3amoney-sexp%29" data-pltdoc="x">Project: The Commerce of XML</a>; here we rely on <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span> to get hold of
|
|
the information. Specifically, the teahpack enables you to retrieve the
|
|
music tracks that your iTunes library contains.</p><p><div class="SIntrapara">While the details vary, an iTunes library maintains some of the following
|
|
kinds of information for each music track, occasionally a bit less:
|
|
</div><div class="SIntrapara"><ul><li><p><span style="font-style: italic">Track ID</span>, a unique identifier for the track with respect
|
|
to your library, example: <span class="stt">442</span></p></li><li><p><span style="font-style: italic">Name</span>, the title of the track, <span class="stt">Wild Child</span></p></li><li><p><span style="font-style: italic">Artist</span>, the producing artists, <span class="stt">Enya</span></p></li><li><p><span style="font-style: italic">Album</span>, the title of the album to which it belongs,
|
|
<span class="stt">A Day Without</span></p></li><li><p><span style="font-style: italic">Genre</span>, the music genre to which the track is assigned,
|
|
<span class="stt">New Age</span></p></li><li><p><span style="font-style: italic">Kind</span>, the encoding of the music, <span class="stt">MPEG audio
|
|
file</span></p></li><li><p><span style="font-style: italic">Size</span>, the size of the file, <span class="stt">4562044</span></p></li><li><p><span style="font-style: italic">Total Time</span>, the length of the track in milliseconds,
|
|
<span class="stt">227996</span></p></li><li><p><span style="font-style: italic">Track Number</span>, the position of the track within the album,
|
|
<span class="stt">2</span></p></li><li><p><span style="font-style: italic">Track Count</span>, the number of tracks on the album,
|
|
<span class="stt">11</span></p></li><li><p><span style="font-style: italic">Year</span>, the year of release, <span class="stt">2000</span></p></li><li><p><span style="font-style: italic">Date Added</span>, when the track was added,
|
|
<span class="stt">2002-7-17 3:55:14</span></p></li><li><p><span style="font-style: italic">Play Count</span>, how many times it was played, <span class="stt">20</span></p></li><li><p><span style="font-style: italic">Play Date</span>, when the track was last played,
|
|
<span class="stt">3388484113</span> Unix seconds</p></li><li><p><span style="font-style: italic">Play Date UTC</span>, when it was last played,
|
|
<span class="stt">2011-5-17 17:35:13</span></p></li></ul></div></p><p>As always, the first task is to choose a BSL data representation for
|
|
this information. In this section, we use <span style="font-weight: bold">two</span> representations for
|
|
music tracks: a structure-based one and another based on
|
|
lists.<span class="refelem"><span class="refcolumn"><span class="refcontent">In addition to <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/batch-io</span></span> teachpack</span>, this section
|
|
relies on <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span>.</span></span></span> While the former records a fixed number of
|
|
attributes per track and only if all information is available, the latter
|
|
comes with whatever information is available represented as data. Each
|
|
serves particular uses well; for some uses, both representations are
|
|
useful.</p><p><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span><span class="RktCmt"> documentation, part 1: </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._itunes-data._ltrack)"></a><span style="font-style: italic">LTracks</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._track%29" class="techoutside" data-pltdoc="x"><span class="techinside">Track</span></a><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">track</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">artist</span><span class="hspace"> </span><span class="RktSym">album</span><span class="hspace"> </span><span class="RktSym">time</span><span class="hspace"> </span><span class="RktSym">track#</span><span class="hspace"> </span><span class="RktSym">added</span><span class="hspace"> </span><span class="RktSym">play#</span><span class="hspace"> </span><span class="RktSym">played</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._itunes-data._track)"></a><span style="font-style: italic">Track</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-track</span><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="stt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="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_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</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_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> An instance records in order: the track</span><span class="RktCmt">'</span><span class="RktCmt">s </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">title, its producing artist, to which album it belongs, </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">its playing time in milliseconds, its position within the </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">album, the date it was added, how often it has been </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">played, and the date when it was last played</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">date</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">year</span><span class="hspace"> </span><span class="RktSym">month</span><span class="hspace"> </span><span class="RktSym">day</span><span class="hspace"> </span><span class="RktSym">hour</span><span class="hspace"> </span><span class="RktSym">minute</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._second%29%29" class="RktValLink" data-pltdoc="x">second</a></span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._itunes-data._date)"></a><span style="font-style: italic">Date</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-date</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="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_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</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_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</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="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> An instance records six pieces of information:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">the date</span><span class="RktCmt">'</span><span class="RktCmt">s year, month (between </span><span class="RktVal">1</span><span class="RktCmt"> and </span><span class="RktVal">12</span><span class="RktCmt"> inclusive), </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">day (between </span><span class="RktVal">1</span><span class="RktCmt"> and </span><span class="RktVal">31</span><span class="RktCmt">), hour (between </span><span class="RktVal">0</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">and </span><span class="RktVal">23</span><span class="RktCmt">), minute (between </span><span class="RktVal">0</span><span class="RktCmt"> and </span><span class="RktVal">59</span><span class="RktCmt">), and </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">second (also between </span><span class="RktVal">0</span><span class="RktCmt"> and </span><span class="RktVal">59</span><span class="RktCmt">).</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._itunes-data._(figure._fig~3aitunes-api-tracks))" x-target-lift="Figure"></a>Figure 75: </span>Representing iTunes tracks as structures (the structures)</span></p></blockquote></div><div class="SIntrapara"><a name="(idx._itunes-data._(gentag._316._itunes-data))"></a> <a name="(idx._itunes-data._(gentag._317._itunes-data))"></a> <a name="(idx._itunes-data._(gentag._318._itunes-data))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._itunes-data._track%29" class="techoutside" data-pltdoc="x"><span class="techinside">Track</span></a><span class="RktCmt"> or </span><span class="RktVal">#false</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates an instance of </span><a href="part_two.html#%28tech._itunes-data._track%29" class="techoutside" data-pltdoc="x"><span class="techinside">Track</span></a><span class="RktCmt"> for legitimate inputs</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">otherwise it produces </span><span class="RktVal">#false</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-track</span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">artist</span><span class="hspace"> </span><span class="RktSym">album</span><span class="hspace"> </span><span class="RktSym">time</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">track#</span><span class="hspace"> </span><span class="RktSym">added</span><span class="hspace"> </span><span class="RktSym">play#</span><span class="hspace"> </span><span class="RktSym">played</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a><span class="RktCmt"> or </span><span class="RktVal">#false</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates an instance of </span><a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a><span class="RktCmt"> for legitimate inputs </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">otherwise it produces </span><span class="RktVal">#false</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">create-date</span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">mo</span><span class="hspace"> </span><span class="RktSym">day</span><span class="hspace"> </span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktSym">m</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a list-of-tracks representation from the</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">text in </span><span class="RktSym">file-name</span><span class="RktCmt"> (an XML export from iTunes)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">read-itunes-as-tracks</span><span class="hspace"> </span><span class="RktSym">file-name</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._itunes-data._(figure._fig~3aitunes-api-tracks-fun))" x-target-lift="Figure"></a>Figure 76: </span>Representing iTunes tracks as structures (the functions)</span></p></blockquote></div></p><p><a href="part_two.html#%28counter._itunes-data._%28figure._fig~3aitunes-api-tracks%29%29" data-pltdoc="x">Figures <span class="FigureRef">75</span></a> and <a href="part_two.html#%28counter._itunes-data._%28figure._fig~3aitunes-api-tracks-fun%29%29" data-pltdoc="x"><span class="FigureRef">76</span></a> introduce
|
|
the structure-based representation of tracks as implemented by
|
|
<span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span>. The <span class="RktSym">track</span> structure type comes with eight
|
|
fields, each representing a particular property of the track. Most fields
|
|
contain atomic kinds of data, such as <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s and <a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a>s; others
|
|
contain <a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a>s, which is a structure type with six fields.
|
|
<span class="sroman">The <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span> exports all predicates and selectors for the
|
|
<span class="RktSym">track</span> and <span class="RktSym">date</span> structure types, but in lieu of
|
|
constructors it provides checked constructors.</p><p>The last element of the description of <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span> is a function that
|
|
reads an iTunes XML library description and delivers a list of tracks,
|
|
<a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. Once you have exported the XML library from some iTunes
|
|
app, you can run the following code snippet to retrieve all the records:</p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">modify the following to use your chosen name</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ITUNES-LOCATION</span><span class="hspace"> </span><span class="RktVal">"itunes.xml"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">itunes-tracks</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">read-itunes-as-tracks</span><span class="hspace"> </span><span class="RktSym">ITUNES-LOCATION</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Save the snippet in the same folder as your iTunes XML export. Remember
|
|
not to use <span class="RktSym">itunes-tracks</span> for examples; it
|
|
is way too large for that. Indeed, it may be so large that reading the file
|
|
every time you run your BSL program in DrRacket will take a lot of
|
|
time. You may therefore wish to comment out this second line
|
|
while you design functions. Uncomment it only when you wish to compute
|
|
information about your iTunes collection.</div></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes1))"></a><span style="font-weight: bold">Exercise</span> 199. While the important data definitions are already
|
|
provided, the first step of the design recipe is still incomplete. Make up
|
|
examples of <a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a>s, <a href="part_two.html#%28tech._itunes-data._track%29" class="techoutside" data-pltdoc="x"><span class="techinside">Track</span></a>s, and <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. These
|
|
examples come in handy for the following exercises as inputs. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes2))"></a><span style="font-weight: bold">Exercise</span> 200. Design the function <span class="RktSym">total-time</span>, which
|
|
consumes an element of <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a> and produces the total amount of play
|
|
time. Once the program is done, compute the total play time of
|
|
your iTunes collection. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes3))"></a><span style="font-weight: bold">Exercise</span> 201. Design <span class="RktSym">select-all-album-titles</span>. The
|
|
function consumes an <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a> and produces the list of album titles
|
|
as a <a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a>.</p><p>Also design the function <span class="RktSym">create-set</span>. It consumes a
|
|
<a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a> and constructs one that contains every
|
|
<a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> from the given list exactly once. <span style="font-weight: bold">Hint</span> If <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>
|
|
<span class="RktSym">s</span> is at the front of the given list and occurs in the rest of the
|
|
list, too, <span class="RktSym">create-set</span> does not keep <span class="RktSym">s</span>.</p><p>Finally design <span class="RktSym">select-album-titles/unique</span>, which consumes an
|
|
<a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a> and produces a list of unique album titles. Use this
|
|
function to determine all album titles in your iTunes collection and also
|
|
find out how many distinct albums it contains. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes4))"></a><span style="font-weight: bold">Exercise</span> 202. Design <span class="RktSym">select-album</span>. The function consumes
|
|
the title of an album and an <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. It extracts from the latter
|
|
the list of tracks that belong to the given album. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes4%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes5))"></a><span style="font-weight: bold">Exercise</span> 203. Design <span class="RktSym">select-album-date</span>. The function
|
|
consumes the title of an album, a date, and an <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. It extracts
|
|
from the latter the list of tracks that belong to the given album and have
|
|
been played after the given date. <span style="font-weight: bold">Hint</span> You must design a function
|
|
that consumes two <a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a>s and determines whether the first occurs
|
|
before the second. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes5%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes6))"></a><span style="font-weight: bold">Exercise</span> 204. Design <span class="RktSym">select-albums</span>. The function
|
|
consumes an element of <a href="part_two.html#%28tech._itunes-data._ltrack%29" class="techoutside" data-pltdoc="x"><span class="techinside">LTracks</span></a>. It produces a list of <span class="RktSym">LTracks</span>, one per
|
|
album. Each album is uniquely identified by its title and shows up in the
|
|
result only once. <span style="font-weight: bold">Hints</span> (1) You want to use some of the solutions of
|
|
the preceding exercises. (2) The function that groups consumes two
|
|
lists: the list of album titles and the list of tracks; it considers the
|
|
latter as atomic until it is handed over to an auxiliary function. See
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3adictionary2%29%29" data-pltdoc="x">exercise 196</a>. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes6%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span style="font-weight: bold">Terminology</span> The functions whose names start with <span class="RktSym">select-</span>
|
|
are so-called <span style="font-style: italic">database queries</span>. See <a href="part_four.html#%28part._db._sec~3aproj-db%29" data-pltdoc="x">Project: Database</a> for more details. <span style="font-weight: bold">End</span></p><p><div class="SIntrapara"><a name="(idx._itunes-data._(gentag._319._itunes-data))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span><span class="RktCmt"> documentation, part 2: </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._itunes-data._llist)"></a><span style="font-style: italic">LLists</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._lassoc%29" class="techoutside" data-pltdoc="x"><span class="techinside">LAssoc</span></a><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._itunes-data._lassoc)"></a><span style="font-style: italic">LAssoc</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._association%29" class="techoutside" data-pltdoc="x"><span class="techinside">Association</span></a><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._lassoc%29" class="techoutside" data-pltdoc="x"><span class="techinside">LAssoc</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._itunes-data._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"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..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"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._itunes-data._bsdn%29" class="techoutside" data-pltdoc="x"><span class="techinside">BSDN</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="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._itunes-data._bsdn)"></a><span style="font-style: italic">BSDN</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._itunes-data._date%29" class="techoutside" data-pltdoc="x"><span class="techinside">Date</span></a></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates a list of lists representation for all tracks in </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktSym">file-name</span><span class="RktCmt">, which must be an XML export from iTunes </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">read-itunes-as-lists</span><span class="hspace"> </span><span class="RktSym">file-name</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._itunes-data._(figure._fig~3aitunes-api-lists))" x-target-lift="Figure"></a>Figure 77: </span>Representing iTunes tracks as lists</span></p></blockquote></div></p><p><a href="part_two.html#%28counter._itunes-data._%28figure._fig~3aitunes-api-lists%29%29" data-pltdoc="x">Figure <span class="FigureRef">77</span></a> shows how <span class="sroman">the <span class="Smaller"><span style="font-style: italic">2htdp/itunes</span></span> teachpack</span> represents
|
|
tracks with lists. An <a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a> is a list of track representations,
|
|
each of which is a list of lists pairing <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s with four kinds of
|
|
values. The <span class="RktSym">read-itunes-as-lists</span> function reads an iTunes XML
|
|
library and produces an element of <a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a>. Hence, you get access
|
|
to all track information if you add the following definitions to your
|
|
program:</p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">modify the following to use your chosen name</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ITUNES-LOCATION</span><span class="hspace"> </span><span class="RktVal">"itunes.xml"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">list-tracks</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">read-itunes-as-lists</span><span class="hspace"> </span><span class="RktSym">ITUNES-LOCATION</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Then save it in the same folder where the iTunes library is stored.</div></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes10))"></a><span style="font-weight: bold">Exercise</span> 205. Develop examples of <a href="part_two.html#%28tech._itunes-data._lassoc%29" class="techoutside" data-pltdoc="x"><span class="techinside">LAssoc</span></a> and
|
|
<a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a>, that is, the list representation of tracks and lists of
|
|
such tracks. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes10%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes11))"></a><span style="font-weight: bold">Exercise</span> 206. Design the function <span class="RktSym">find-association</span>. It
|
|
consumes three arguments: a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> called <span class="RktSym">key</span>, an
|
|
<a href="part_two.html#%28tech._itunes-data._lassoc%29" class="techoutside" data-pltdoc="x"><span class="techinside">LAssoc</span></a>, and an element of <a href="part_one.html#%28tech._any%29" class="techoutside" data-pltdoc="x"><span class="techinside">Any</span></a> called <span class="RktSym">default</span>. It
|
|
produces the first <a href="part_two.html#%28tech._itunes-data._association%29" class="techoutside" data-pltdoc="x"><span class="techinside">Association</span></a> whose first item is equal to
|
|
<span class="RktSym">key</span>, or <span class="RktSym">default</span> if there is no such
|
|
<span class="RktSym">Association</span>.</p><p><span style="font-weight: bold">Note</span> Read up on <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._assoc%29%29" class="RktValLink" data-pltdoc="x">assoc</a></span> after you have designed this
|
|
function. <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes11%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes12))"></a><span style="font-weight: bold">Exercise</span> 207. Design <span class="RktSym">total-time/list</span>,
|
|
which consumes an <a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a> and produces the total amount of play
|
|
time. <span style="font-weight: bold">Hint</span> Solve <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes11%29%29" data-pltdoc="x">exercise 206</a> first.</p><p>Once you have completed the design, compute the total play time of your
|
|
iTunes collection. Compare this result with the time that the
|
|
<span class="RktSym">total-time</span> function from <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes2%29%29" data-pltdoc="x">exercise 200</a> computes. Why is
|
|
there a difference? <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes12%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._itunes-data._(exercise._ex~3aitunes13))"></a><span style="font-weight: bold">Exercise</span> 208. Design <span class="RktSym">boolean-attributes</span>. The function
|
|
consumes an <a href="part_two.html#%28tech._itunes-data._llist%29" class="techoutside" data-pltdoc="x"><span class="techinside">LLists</span></a> and produces the <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s that are
|
|
associated with a <a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a> attribute. <span style="font-weight: bold">Hint</span> Use <span class="RktSym">create-set</span> from
|
|
<a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes3%29%29" data-pltdoc="x">exercise 201</a>.</p><p>Once you are done, determine how many Boolean-valued attributes your iTunes
|
|
library employs for its tracks. Do they make sense? <a href="part_two.html#%28counter._itunes-data._%28exercise._ex~3aitunes13%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span style="font-weight: bold">Note</span> A list-based representation is a bit less organized than a
|
|
structure-based one. The word <span style="font-style: italic">semi-structured</span> is occasionally
|
|
used in this context. Such list-representations accommodate properties
|
|
that show up rarely and thus don’t fit the structure type. People often
|
|
use such representations to explore unknown information and later
|
|
introduce structures when the format is well-known. Design a function
|
|
<span class="RktSym">track-as-struct</span>, which converts an <a href="part_two.html#%28tech._itunes-data._lassoc%29" class="techoutside" data-pltdoc="x"><span class="techinside">LAssoc</span></a> to a
|
|
<a href="part_two.html#%28tech._itunes-data._track%29" class="techoutside" data-pltdoc="x"><span class="techinside">Track</span></a> when possible. <span style="font-weight: bold">End</span></p><h4>12.3<tt> </tt><a name="(part._sec~3apermute-composition)"></a>Word Games, Composition Illustrated</h4><p><div class="SIntrapara">Some of you solve word puzzles in newspapers and magazines. Try this:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Given a word, find all words that are
|
|
made up from the same letters. For example “cat” also spells “act.”</p></blockquote></div><div class="SIntrapara">Let’s work through an example. Suppose you are given “dear.” There are
|
|
twenty-four possible arrangements of the four letters:
|
|
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0"><tr><td><p>ader</p></td><td><p><span class="hspace"> </span></p></td><td><p>aedr</p></td><td><p><span class="hspace"> </span></p></td><td><p>aerd</p></td><td><p><span class="hspace"> </span></p></td><td><p>adre</p></td><td><p><span class="hspace"> </span></p></td><td><p>arde</p></td><td><p><span class="hspace"> </span></p></td><td><p>ared</p></td></tr><tr><td><p>daer</p></td><td><p><span class="hspace"> </span></p></td><td><p>eadr</p></td><td><p><span class="hspace"> </span></p></td><td><p>eard</p></td><td><p><span class="hspace"> </span></p></td><td><p>dare</p></td><td><p><span class="hspace"> </span></p></td><td><p>rade</p></td><td><p><span class="hspace"> </span></p></td><td><p>raed</p></td></tr><tr><td><p>dear</p></td><td><p><span class="hspace"> </span></p></td><td><p>edar</p></td><td><p><span class="hspace"> </span></p></td><td><p>erad</p></td><td><p><span class="hspace"> </span></p></td><td><p>drae</p></td><td><p><span class="hspace"> </span></p></td><td><p>rdae</p></td><td><p><span class="hspace"> </span></p></td><td><p>read</p></td></tr><tr><td><p>dera</p></td><td><p><span class="hspace"> </span></p></td><td><p>edra</p></td><td><p><span class="hspace"> </span></p></td><td><p>erda</p></td><td><p><span class="hspace"> </span></p></td><td><p>drea</p></td><td><p><span class="hspace"> </span></p></td><td><p>rdea</p></td><td><p><span class="hspace"> </span></p></td><td><p>reda</p></td></tr></table></blockquote></div><div class="SIntrapara">In this list, there are three legitimate words: “read,” “dear,” and “dare.”</div></p><p><span style="font-weight: bold">Note</span> If a word contains the same letter twice, the collection of all
|
|
re-arrangements may contain several copies of the same string. For our
|
|
purposes, this is acceptable. For a realistic program, you may wish to
|
|
avoid duplicate entries by using sets instead of lists. See <a href="part_two.html#%28part._sec~3alist-set%29" data-pltdoc="x">A Note on Lists and Sets</a>. <span style="font-weight: bold">End</span></p><p>A systematic enumeration of all possible arrangements is clearly a task for
|
|
a program, as is the search in an English-language
|
|
dictionary.<span class="refelem"><span class="refcolumn"><span class="refcontent">See <a href="part_two.html#%28part._sec~3adict%29" data-pltdoc="x">Real-World Data: Dictionaries</a> for dealing with real-world
|
|
dictionaries.</span></span></span> This section covers the design of the search function,
|
|
leaving the solution of the other problem to the next section. By
|
|
separating the two, this first section can focus on the high-level ideas
|
|
of systematic program design.</p><p>Let’s imagine for a moment how we might solve the problem by hand. If you
|
|
had enough time, you might enumerate all possible arrangements of all
|
|
letters in a given word and then just pick those variants that also occur
|
|
in a dictionary. Clearly, a program can proceed in this way too, and this
|
|
suggests a natural design by composition, but, as always, we proceed
|
|
systematically and start by choosing a data representation for our inputs
|
|
and outputs.</p><p><div class="SIntrapara">At least at first glance, it is natural to represent words as
|
|
<a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s and the result as a list of words or
|
|
<a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a>. Based on this choice, we can formulate a signature
|
|
and purpose statement: <a name="(idx._(gentag._320))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds all words that use the same letters as </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Next, we need some examples. If the given word is “cat,” we are dealing
|
|
with three letters: <span class="emph">c</span>, <span class="emph">a</span>, and <span class="emph">t</span>. Some playing around
|
|
suggests six arrangements of these letters: <span class="emph">cat</span>, <span class="emph">cta</span>,
|
|
<span class="emph">tca</span>, <span class="emph">tac</span>, <span class="emph">act</span>, and <span class="emph">atc</span>. Two of these are
|
|
actual words: “cat” and “act.” Because <span class="RktSym">alternative-words</span>
|
|
produces a list of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s, there are two ways to represent the
|
|
result: <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"act"</span><span class="stt"> </span><span class="RktVal">"cat"</span><span class="RktPn">)</span> and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"cat"</span><span class="stt"> </span><span class="RktVal">"act"</span><span class="RktPn">)</span>. Fortunately, BSL comes with a way to say the function returns
|
|
one of two possible 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-member-of%29%29" class="RktStxLink" data-pltdoc="x">check-member-of</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"act"</span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="hspace"> </span><span class="RktVal">"act"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Stop! Read up on <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-member-of%29%29" class="RktStxLink" data-pltdoc="x">check-member-of</a></span> in the documentation.</div></p><p><div class="SIntrapara">Working through this example exposes two problems:
|
|
</div><div class="SIntrapara"><ul><li><p>The first one is about testing. Suppose we had used the word “rat”
|
|
for which there are three alternatives: “rat,” “tar,” and “art.” In
|
|
this case, we would have to formulate six lists, each of which might be the
|
|
result of the function. For a word like “dear” with four possible
|
|
alternatives, formulating a test would be even harder.</p></li><li><p>The second problem concerns the choice of word representation.
|
|
Although <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> looks natural at first, the examples clarify that
|
|
some of our functions must view words as sequences of letters, with the
|
|
possibility of rearranging them at will. It is possible to rearrange the
|
|
letters within a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>, but lists of letters are obviously better
|
|
suited for this purpose.</p></li></ul></div><div class="SIntrapara">Let’s deal with these problems one at a time, starting with tests.</div></p><p>Assume we wish to formulate a test for <span class="RktSym">alternative-words</span> and
|
|
<span class="RktVal">"rat"</span>. From the above, we know that the result must contain
|
|
<span class="RktVal">"rat"</span>, <span class="RktVal">"tar"</span>, and <span class="RktVal">"art"</span>, but we cannot know in
|
|
which order these words show up in the result.</p><p><div class="SIntrapara">In this situation, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span> comes in <a name="(idx._(gentag._321))"></a>
|
|
handy.<span class="refelem"><span class="refcolumn"><span class="refcontent">See <a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a>.</span></span></span> We can use it
|
|
with a function that checks whether a list of <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s
|
|
contains our three <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s: <a name="(idx._(gentag._322))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">all-words-from-rat?</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"rat"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"art"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"tar"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">With this function, it is easy to formulate a test for <span class="RktSym">alternative-words</span>: <a name="(idx._(gentag._323))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktVal">"rat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">all-words-from-rat?</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><span style="font-weight: bold">Note on Data versus Design</span> What this discussion suggests is that the
|
|
<span class="RktSym">alternative-words</span> function constructs a set, not a list. For a detailed
|
|
discussion of the differences, see <a href="part_two.html#%28part._sec~3alist-set%29" data-pltdoc="x">A Note on Lists and Sets</a>. Here it suffices
|
|
to know that sets represent collections of values <span style="font-weight: bold">without</span> regard to
|
|
the ordering of the values or how often these values occur. When a language
|
|
comes without support for data representations of sets, programmers tend to
|
|
resort to a close alternative, such as the <span class="RktSym">List-of-strings</span>
|
|
representation here. As programs grow, this choice may haunt programmers,
|
|
but addressing this kind of problem is the subject of the second book. <span style="font-weight: bold">End</span></p><p><div class="SIntrapara"><a name="(idx._(gentag._324))"></a>
|
|
<a name="(idx._(gentag._325))"></a>
|
|
<a name="(idx._(gentag._326))"></a>
|
|
<a name="(idx._(gentag._327))"></a>
|
|
<a name="(idx._(gentag._328))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">all-words-from-rat?</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"rat"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"art"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span><span class="hspace"> </span><span class="RktVal">"tar"</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds all words that the letters of some given word spell</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-member-of%29%29" class="RktStxLink" data-pltdoc="x">check-member-of</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"act"</span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"cat"</span><span class="hspace"> </span><span class="RktVal">"act"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktVal">"rat"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">all-words-from-rat?</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">alternative-words</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">in-dictionary</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words->strings</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string->word</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">turns all </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktCmt">s in </span><span class="RktSym">low</span><span class="RktCmt"> into </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">s </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words->strings</span><span class="hspace"> </span><span class="RktSym">low</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-strings</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">picks out all those </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt">s that occur in the dictionary </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">in-dictionary</span><span class="hspace"> </span><span class="RktSym">los</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></div><div class="SIntrapara"><a name="(idx._(gentag._329))"></a></div></p></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aalternative-words))" x-target-lift="Figure"></a>Figure 78: </span>Finding alternative words</span></p></blockquote></div></p><p><div class="SIntrapara">For the problem with a word representation, we punt to the next
|
|
section. Specifically, we say that the next section introduces (1) a data
|
|
representation for <a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a>s suitable for rearranging letters, (2) a
|
|
data definition for <a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a>, and (3) a function that maps a
|
|
<a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a> to a <a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a>, meaning a list of all possible
|
|
rearrangements: <a name="(idx._(gentag._330))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><span style="font-style: italic">Word</span><span class="RktCmt"> is </span>...</td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><span style="font-style: italic">List-of-words</span><span class="RktCmt"> is </span>...</td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds all rearrangements of </span><span class="RktSym">word</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktSym">word</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">word</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3astring2word))"></a><span style="font-weight: bold">Exercise</span> 209. The above leaves us with two additional wishes:
|
|
a function that consumes a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> and produces its corresponding
|
|
<a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a>, and a function for the opposite direction. Here are the
|
|
wish-list entries:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts </span><span class="RktSym">s</span><span class="RktCmt"> to the chosen word representation </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string->word</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">converts </span><span class="RktSym">w</span><span class="RktCmt"> to a string</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">word->string</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Look up the data definition for <a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a> in the next section and
|
|
complete the definitions of <span class="RktSym">string->word</span> and
|
|
<span class="RktSym">word->string</span>. <span style="font-weight: bold">Hint</span> You may wish to look in the list of
|
|
functions that BSL provides. <a href="part_two.html#%28counter._%28exercise._ex~3astring2word%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p>With those two small problems out of the way, we return to the design of
|
|
<span class="RktSym">alternative-words</span>. We now have: (1) a signature, (2) a purpose
|
|
statement, (3) examples and test, (4) an insight concerning our choice of
|
|
data representation, and (5) an idea of how to decompose the problem into
|
|
two major steps.</p><p><div class="SIntrapara">So, instead of creating a template, we write down the composition we have
|
|
in mind:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">in-dictionary</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">The expression says that, given a word <span class="RktSym">s</span>, we use
|
|
<span class="RktSym">arrangements</span> to create a list of all possible rearrangements of
|
|
the letters and <span class="RktSym">in-dictionary</span> to select those rearrangements
|
|
that also occur in a dictionary.</div></p><p>Stop! Look up the signatures for the two functions to make sure the
|
|
composition works out. What exactly do you need to check?</p><p><div class="SIntrapara">What this expression fails to capture is the fourth point, the decision not
|
|
to use plain strings to rearrange the letters. Before we hand <span class="RktSym">s</span>
|
|
to <span class="RktSym">arrangements</span>, we need to convert it into a word. Fortunately,
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3astring2word%29%29" data-pltdoc="x">exercise 209</a> asks for just such a function:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">in-dictionary</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string->word</span><span class="hspace"> </span><span class="RktSym">s</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">Similarly, we need to convert the resulting list of words to a list of
|
|
strings. While <a href="part_two.html#%28counter._%28exercise._ex~3astring2word%29%29" data-pltdoc="x">exercise 209</a> asks for a function that converts a
|
|
single word, here we need a function that deals with lists of them.
|
|
Time to make another wish:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">in-dictionary</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">words->strings</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">string->word</span><span class="hspace"> </span><span class="RktSym">s</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! What is the signature for <span class="RktSym">words->strings</span> and what is its
|
|
purpose?</div></p><p><a href="part_two.html#%28counter._%28figure._fig~3aalternative-words%29%29" data-pltdoc="x">Figure <span class="FigureRef">78</span></a> collects all the pieces. The following
|
|
exercises ask you to design the remaining functions.</p><p><a name="(counter._(exercise._ex~3awords2strings))"></a><span style="font-weight: bold">Exercise</span> 210. Complete the design of the
|
|
<span class="RktSym">words->strings</span> function specified in
|
|
<a href="part_two.html#%28counter._%28figure._fig~3aalternative-words%29%29" data-pltdoc="x">figure <span class="FigureRef">78</span></a>. <span style="font-weight: bold">Hint</span> Use your solution to
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3astring2word%29%29" data-pltdoc="x">exercise 209</a>. <a href="part_two.html#%28counter._%28exercise._ex~3awords2strings%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3ain-dictionary))"></a><span style="font-weight: bold">Exercise</span> 211. Complete the design of
|
|
<span class="RktSym">in-dictionary</span>, specified in
|
|
<a href="part_two.html#%28counter._%28figure._fig~3aalternative-words%29%29" data-pltdoc="x">figure <span class="FigureRef">78</span></a>. <span style="font-weight: bold">Hint</span> See <a href="part_two.html#%28part._sec~3adict%29" data-pltdoc="x">Real-World Data: Dictionaries</a> for
|
|
how to read a dictionary. <a href="part_two.html#%28counter._%28exercise._ex~3ain-dictionary%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>12.4<tt> </tt><a name="(part._sec~3apermute)"></a>Word Games, the Heart of the Problem</h4><p>The goal is to design <span class="RktSym">arrangements</span>, a function that
|
|
consumes a <a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a> and produces a list of the word’s letter-by-letter
|
|
rearrangements.<span class="refelem"><span class="refcolumn"><span class="refcontent">The mathematical term is
|
|
<span style="font-style: italic">permutations</span>.</span></span></span> This extended exercise reinforces the need for
|
|
deep wish lists, that is, a list of desired functions that seems to grow
|
|
with every function you finish.</p><p><div class="SIntrapara">As mentioned, <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a>s could serve as a representation of words, but
|
|
a <a href="part_one.html#%28tech._string%29" class="techoutside" data-pltdoc="x"><span class="techinside">String</span></a> is atomic and the very fact that <span class="RktSym">arrangements</span>
|
|
needs to rearrange its letters calls for a different representation.
|
|
Our chosen data representation of a word is therefore a list of
|
|
<a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a>s where each item in the input represents a letter:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._word)"></a><span style="font-style: italic">Word</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> or</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="stt"> </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> a </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktCmt"> is a list of </span><a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a><span class="RktCmt">s (letters)</span></td></tr></table></blockquote></div></p><p><a name="(counter._(exercise._ex~3apermutations1))"></a><span style="font-weight: bold">Exercise</span> 212. Write down the data definition for
|
|
<a name="(tech._list._of._word)"></a><span style="font-style: italic">List-of-words</span>. Make up examples of <a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a>s
|
|
and <a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a>. Finally, formulate the functional example from
|
|
above with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span>. Instead of the full
|
|
example, consider working with a word of just two letters, say
|
|
<span class="RktVal">"d"</span> and <span class="RktVal">"e"</span>. <a href="part_two.html#%28counter._%28exercise._ex~3apermutations1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">The template of <span class="RktSym">arrangements</span> is that of a list-processing function:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">Word</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._list._of._word%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of-words</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">creates all rearrangements of the letters in </span><span class="RktSym">w</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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></p><p><div class="SIntrapara">In preparation of the fifth step, let’s look at the template’s <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> lines:
|
|
</div><div class="SIntrapara"><ol><li><p>If the input is <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span>, there is only one possible
|
|
rearrangement of the input: the <span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span> word. Hence the result is
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span>, the list that contains the empty list as the only
|
|
item.</p></li><li><p><div class="SIntrapara">Otherwise there is a first letter in the word, and <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="stt"> </span><span class="RktSym">w</span><span class="RktPn">)</span>
|
|
is that letter. Also, the recursion produces the list of all possible
|
|
rearrangements for the rest of the word. For example, if the list 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/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">then the recursion is <span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"e"</span><span class="stt"> </span><span class="RktVal">"r"</span><span class="RktPn">)</span><span class="RktPn">)</span>. It will
|
|
produce the result
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">To obtain all possible rearrangements for the entire list, we
|
|
must now insert the first item, <span class="RktVal">"d"</span> in our case, into all of these
|
|
words between all possible letters and at the beginning and end.</div></p></li></ol></div></p><p><div class="SIntrapara">Our analysis suggests that we can complete <span class="RktSym">arrangements</span> if we can
|
|
somehow insert one letter into all positions of many different
|
|
words. The last aspect of this task description implicitly mentions lists
|
|
and, following the advice of this chapter, calls for an auxiliary
|
|
function. Let’s call this function <span class="RktSym">insert-everywhere/in-all-words</span>
|
|
and let’s use it to complete the definition of <span class="RktSym">arrangements</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">insert-everywhere/in-all-words</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">arrangements</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace"> </span><span class="RktSym">w</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><a name="(counter._(exercise._ex~3apermutations))"></a><span style="font-weight: bold">Exercise</span> 213. Design <span class="RktSym">insert-everywhere/in-all-words</span>.
|
|
It consumes a <a href="part_one.html#%28tech._1string%29" class="techoutside" data-pltdoc="x"><span class="techinside">1String</span></a> and a list of words. The result is a list of
|
|
words like its second argument, but with the first argument inserted at the
|
|
beginning, between all letters, and at the end of all words of the given
|
|
list.</p><p>Start with a complete wish-list entry. Supplement it with tests for empty
|
|
lists, a list with a one-letter word, and another list with a two-letter
|
|
word, and the like. Before you continue, study the following three hints carefully.</p><p><div class="SIntrapara"><span style="font-weight: bold">Hints</span> (1) Reconsider the example from above. It says that <span class="RktVal">"d"</span> needs
|
|
to be inserted into the words <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"e"</span><span class="stt"> </span><span class="RktVal">"r"</span><span class="RktPn">)</span> and
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">"r"</span><span class="stt"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span>. The following application is therefore
|
|
one natural candidate for an example:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">insert-everywhere/in-all-words</span><span class="hspace"> </span><span class="RktVal">"d"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"r"</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">(2) You want to use the BSL+ operation <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span>, which
|
|
consumes two lists and produces the concatenation of the two lists:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="hspace"> </span><span class="RktVal">"b"</span><span class="hspace"> </span><span class="RktVal">"c"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"d"</span><span class="hspace"> </span><span class="RktVal">"e"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(list "a" "b" "c" "d" "e")</span></p></td></tr></table></blockquote></div><div class="SIntrapara">The development of functions like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._append%29%29" class="RktValLink" data-pltdoc="x">append</a></span> is the subject of <a href="part_four.html#%28part._ch~3asimu%29" data-pltdoc="x">Simultaneous Processing</a>.</div></p><p>(3) This solution of this exercise is a series of functions. Patiently
|
|
stick to the design recipe and systematically work through your wish list. <a href="part_two.html#%28counter._%28exercise._ex~3apermutations%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3apermutations2))"></a><span style="font-weight: bold">Exercise</span> 214. Integrate <span class="RktSym">arrangements</span> with the
|
|
partial program from <a href="part_two.html#%28part._sec~3apermute-composition%29" data-pltdoc="x">Word Games, Composition Illustrated</a>. After making
|
|
sure that the entire <a name="(idx._(gentag._331))"></a>suite of tests passes, run it on some of your favorite
|
|
examples. <a href="part_two.html#%28counter._%28exercise._ex~3apermutations2%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>12.5<tt> </tt><a name="(part._sec~3aworms)"></a>Feeding Worms</h4><p><span style="font-weight: bold">Worm</span>—<wbr></wbr>also known as <span class="emph">Snake</span>—<wbr></wbr>is one of the oldest computer
|
|
games. When the game starts, a worm and a piece of food appear. The worm is
|
|
moving toward a wall. Don’t let it reach the wall; otherwise the game is
|
|
over. Instead, use the arrow keys to control the worm’s movements.</p><p>The goal of the game is to have the worm eat as much food as possible. As the
|
|
worm eats the food, it becomes longer; more and more segments appear. Once a
|
|
piece of food is digested, another piece appears. The worm’s growth
|
|
endangers the worm itself, though. As it grows long enough, it can run into
|
|
itself and, if it does, the game is over, too.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_105.png" alt="image" width="106.0" height="106.0"/><span class="hspace"> </span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_106.png" alt="image" width="106.0" height="106.0"/><span class="hspace"> </span><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_107.png" alt="image" width="106.0" height="106.0"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aworm))" x-target-lift="Figure"></a>Figure 79: </span>Playing Worm</span></p></blockquote><p><a href="part_two.html#%28counter._%28figure._fig~3aworm%29%29" data-pltdoc="x">Figure <span class="FigureRef">79</span></a> displays a sequence of screen shots that illustrates how
|
|
the game works in practice. On the left, you see the initial setting. The
|
|
worm consists of a single red segment, its head. It is moving toward the
|
|
food, which is displayed as a green disk. The screen shot in the center
|
|
shows a situation when the worm is about to eat some food. In the right-most
|
|
screen shot the worm has run into the right wall. The game is over; the
|
|
player scored 11 points.</p><p>The following exercises guide you through the design and implementation of a
|
|
Worm game. Like <a href="part_two.html#%28part._sec~3asil%29" data-pltdoc="x">Structures in Lists</a>, these exercises illustrate how to tackle a
|
|
nontrivial problem via <a name="(idx._(gentag._332))"></a>iterative refinement. That is, you don’t design the
|
|
entire interactive program all at once but in several stages, called
|
|
<span style="font-style: italic">iteration</span>s. Each iteration adds details and refines the
|
|
program—<wbr></wbr>until it satisfies you or your customer. If you aren’t satisfied
|
|
with the outcome of the exercises, feel free to create variations.</p><p><a name="(counter._(exercise._ex~3aworm1))"></a><span style="font-weight: bold">Exercise</span> 215. Design a world program that continually
|
|
moves a one-segment worm and enables a player to control the movement of
|
|
the worm with the four cardinal arrow keys. Your program should use a red
|
|
disk to render the one-and-only segment of the worm. For each clock tick,
|
|
the worm should move a diameter.</p><p><span style="font-weight: bold">Hints</span> (1) Reread <a href="part_one.html#%28part._.D.K._sec~3adesign-world%29" data-pltdoc="x">Designing World Programs</a> to
|
|
recall how to design world programs. When you define the <span class="RktSym">worm-main</span>
|
|
function, use the rate at which the clock ticks as its argument. See the
|
|
documentation for <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-tick%29%29" class="RktStxLink" data-pltdoc="x">on-tick</a></span> on how to describe the rate. (2) When
|
|
you develop a data representation for the worm, contemplate the use of two
|
|
different kinds of representations: a physical representation and a
|
|
logical one. The <span style="font-weight: bold">physical</span> representation keeps track of the actual
|
|
physical <span style="font-weight: bold">position</span> of the worm on the canvas; the <span style="font-weight: bold">logical</span> one
|
|
counts how many (widths of) segments the worm is from the left and the
|
|
top. For which of the two is it easier to change the physical appearances
|
|
(size of worm segment, size of game box) of the “game”? <a href="part_two.html#%28counter._%28exercise._ex~3aworm1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aworm2))"></a><span style="font-weight: bold">Exercise</span> 216. Modify your program from <a href="part_two.html#%28counter._%28exercise._ex~3aworm1%29%29" data-pltdoc="x">exercise 215</a> so
|
|
that it stops if the worm has reached the walls of the world. When the
|
|
program stops because of this condition, it should render the final scene
|
|
with the text <span class="RktVal">"worm hit border"</span> in the lower left of the world scene. <span style="font-weight: bold">Hint</span>
|
|
You can use the <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._stop-when%29%29" class="RktStxLink" data-pltdoc="x">stop-when</a></span> clause in <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> to render the
|
|
last world in a special way. <a href="part_two.html#%28counter._%28exercise._ex~3aworm2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aworm3))"></a><span style="font-weight: bold">Exercise</span> 217. Develop a data representation for worms with tails. A
|
|
worm’s tail is a possibly empty sequence of “connected” segments. Here
|
|
“connected” means that the coordinates of a segment differ from those of
|
|
its predecessor in at most one direction. To keep things simple, treat all
|
|
segments—<wbr></wbr>head and tail segments—<wbr></wbr>the same.</p><p>Now modify your program from <a href="part_two.html#%28counter._%28exercise._ex~3aworm1%29%29" data-pltdoc="x">exercise 215</a> to accommodate a
|
|
multi-segment worm. Keep things simple: (1) your program may render all
|
|
worm segments as red disks and (2) ignore that the worm may run into the
|
|
wall or itself. <span style="font-weight: bold">Hint</span> One way to realize the worm’s movement
|
|
is to add a segment in the direction in which it is moving and to delete
|
|
the last one. <a href="part_two.html#%28counter._%28exercise._ex~3aworm3%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara"><a name="(idx._(gentag._333))"></a>
|
|
<a name="(idx._(gentag._334))"></a>
|
|
<a name="(idx._(gentag._335))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="Herefigure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-satisfied%29%29" class="RktStxLink" data-pltdoc="x">check-satisfied</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">food-create</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">not=-1-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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">food-create</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">food-check-create</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._make-posn%29%29" class="RktValLink" data-pltdoc="x">make-posn</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace"> </span><span class="RktSym">MAX</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span><span class="hspace"> </span><span class="RktSym">MAX</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">generative recursion </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">food-check-create</span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">candidate</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">candidate</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">food-create</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">candidate</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_one.html#%28tech._posn%29" class="techoutside" data-pltdoc="x"><span class="techinside">Posn</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">use for testing only </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">not=-1-1?</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._not%29%29" class="RktValLink" data-pltdoc="x">not</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._and%29%29" class="RktStxLink" data-pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-x%29%29" class="RktValLink" data-pltdoc="x">posn-x</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._posn-y%29%29" class="RktValLink" data-pltdoc="x">posn-y</a></span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3arandom~3aplacement))" x-target-lift="Figure"></a>Figure 80: </span>Random placement of food</span></p></blockquote></div></p><p><a name="(counter._(exercise._ex~3aworm4))"></a><span style="font-weight: bold">Exercise</span> 218. Redesign your program from <a href="part_two.html#%28counter._%28exercise._ex~3aworm3%29%29" data-pltdoc="x">exercise 217</a>
|
|
so that it stops if the worm has run into the walls of the world or into
|
|
itself. Display a message like the one in <a href="part_two.html#%28counter._%28exercise._ex~3aworm2%29%29" data-pltdoc="x">exercise 216</a> to explain
|
|
whether the program stopped because the worm hit the wall or because it
|
|
ran into itself.</p><p><span style="font-weight: bold">Hints</span> (1) To determine whether a worm is going to run into itself,
|
|
check whether the position of the head would coincide with one of its old
|
|
tail segments if it moved. (2) Read up on the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span> function. <a href="part_two.html#%28counter._%28exercise._ex~3aworm4%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3aworm5))"></a><span style="font-weight: bold">Exercise</span> 219. Equip your program from <a href="part_two.html#%28counter._%28exercise._ex~3aworm4%29%29" data-pltdoc="x">exercise 218</a> with food. At
|
|
any point in time, the box should contain one piece of food. To keep things
|
|
simple, a piece of food is of the same size as a worm segment. When the worm’s
|
|
head is located at the same position as the food, the worm eats the food,
|
|
meaning the worm’s tail is extended by one segment. As the piece of food is
|
|
eaten, another one shows up at a different location.</p><p>Adding food to the game requires changes to the data representation of
|
|
world states. In addition to the worm, the states now also include a
|
|
representation of the food, especially its current location. A change to
|
|
the game representation suggests new functions for dealing with events,
|
|
though these functions can reuse the functions for the worm (from
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3aworm4%29%29" data-pltdoc="x">exercise 218</a>) and their test cases. It also means that the tick
|
|
handler must not only move the worm; in addition it must manage the eating
|
|
process and the creation of new food.</p><p>Your program should place the food randomly within the box. To do so
|
|
properly, you need a design technique that you haven’t seen
|
|
before—<wbr></wbr>so-called generative recursion, which is introduced in
|
|
<a href="part_five.html" data-pltdoc="x">Generative Recursion</a>—<wbr></wbr>so we provide these functions in
|
|
<a href="part_two.html#%28counter._%28figure._fig~3arandom~3aplacement%29%29" data-pltdoc="x">figure <span class="FigureRef">80</span></a>.<span class="refelem"><span class="refcolumn"><span class="refcontent">For the workings of
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._random%29%29" class="RktValLink" data-pltdoc="x">random</a></span>, read the manual or <a href="part_one.html#%28counter._mix._%28exercise._mix-ufo-move%29%29" data-pltdoc="x">exercise 99</a>.</span></span></span> Before you use
|
|
them, however, explain how these functions work—<wbr></wbr>assuming <span class="RktSym">MAX</span> is
|
|
greater than <span class="RktVal">1</span>—<wbr></wbr>and then formulate purpose statements.</p><p><span style="font-weight: bold">Hints</span> (1) One way to interpret “eating” is to say that the head moves where the
|
|
food used to be located and the tail grows by one segment, inserted where
|
|
the head used to be. Why is this interpretation easy to design as a
|
|
function? (2) We found it useful to add a second parameter to the
|
|
<span class="RktSym">worm-main</span> function for this last step, a <span style="font-weight: bold">Boolean</span> that
|
|
determines whether <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> displays the current state of the
|
|
world in a separate window; see the documentation for <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._state%29%29" class="RktStxLink" data-pltdoc="x">state</a></span> on
|
|
how to ask for this information. <a href="part_two.html#%28counter._%28exercise._ex~3aworm5%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Once you have finished this last exercise, you have a complete worm
|
|
game. Now modify your <span class="RktSym">worm-main</span> function so that it returns the
|
|
length of the final worm. Then use <span class="stt">Create Executable</span>
|
|
(under the <span class="stt">Racket</span> menu) in DrRacket to turn your program into
|
|
something that anybody can launch, not just someone who knows about
|
|
BSL+.</p><p>You may also wish to add extra twists to the game, to make it really your
|
|
game. We experimented with funny end-of-game messages, having several
|
|
different pieces of food around, with placing extra obstacles in the room,
|
|
and a few other ideas. What can you think of?</p><h4>12.6<tt> </tt><a name="(part._sec~3atetris)"></a>Simple Tetris</h4><p><span style="font-weight: bold">Tetris</span> is another game from the early days of software. Since the
|
|
design of a full-fledged Tetris game demands a lot of labor with only
|
|
marginal profit, this section focuses on a simplified version. If you feel
|
|
ambitious, look up how Tetris really works and design a full-fledged
|
|
version.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_108.png" alt="image" width="106" height="106"/>
|
|
<span class="hspace"> </span>
|
|
<img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_109.png" alt="image" width="106" height="106"/>
|
|
<span class="hspace"> </span>
|
|
<img style="vertical-align: 0px; margin: -3px -3px -3px -3px;" src="pict_110.png" alt="image" width="106" height="106"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3atetris))" x-target-lift="Figure"></a>Figure 81: </span>Simple Tetris</span></p></blockquote><p>In our simplified version, the game starts with individual blocks dropping
|
|
from the top of the scene. Once one of them lands on the ground, it comes to a rest
|
|
and another block starts dropping down from some random place. A player
|
|
can control the dropping block with the “left” and “right” arrow
|
|
keys. Once a block lands on the floor of the canvas or on top of some
|
|
already resting block, it comes to rest and becomes immovable. In a short
|
|
time, the blocks stack up; if a stack of blocks reaches the ceiling of
|
|
the canvas, the game is over. Naturally the objective of this game is to
|
|
land as many blocks as possible. See <a href="part_two.html#%28counter._%28figure._fig~3atetris%29%29" data-pltdoc="x">figure <span class="FigureRef">81</span></a> for an
|
|
illustration of the idea.</p><p><div class="SIntrapara">Given this description, we can turn to the <a name="(idx._(gentag._336))"></a>design guidelines for
|
|
interactive programs from <a href="part_one.html#%28part._.D.K._sec~3adesign-world%29" data-pltdoc="x">Designing World Programs</a>. They call for separating constant properties from
|
|
variable ones. The former can be written down as “physical” and
|
|
graphical constants; the latter suggest the data that makes up all
|
|
possible states of the simple Tetris game. So here are some examples:
|
|
</div><div class="SIntrapara"><ul><li><p><div class="SIntrapara">The width and the height of the game are fixed as are the blocks. In
|
|
terms of BSL+, you want definitions like these:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt"># of blocks, horizontally </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">SIZE</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">blocks are squares</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">SCENE-SIZE</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktSym">WIDTH</span><span class="hspace"> </span><span class="RktSym">SIZE</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">BLOCK</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">red squares with black rims</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._overlay%29%29" class="RktValLink" data-pltdoc="x">overlay</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._square%29%29" class="RktValLink" data-pltdoc="x">square</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">SIZE</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._square%29%29" class="RktValLink" data-pltdoc="x">square</a></span><span class="hspace"> </span><span class="RktSym">SIZE</span><span class="hspace"> </span><span class="RktVal">"outline"</span><span class="hspace"> </span><span class="RktVal">"black"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Explain these definitions before you read on.</div></p></li><li><p>The “landscapes” of blocks differ from
|
|
game to game and from clock tick to clock tick. Let’s make this more
|
|
precise. The appearance of the blocks remains the same; their positions
|
|
differ.</p></li></ul></div></p><p>We are now left with the central problem of designing a data representation
|
|
for the dropping blocks and the landscapes of blocks on the ground. When
|
|
it comes to the dropping block, there are again<span class="refelem"><span class="refcolumn"><span class="refcontent">See
|
|
<a href="part_two.html#%28counter._%28exercise._ex~3aworm1%29%29" data-pltdoc="x">exercise 215</a> for a related design decision.</span></span></span> two possibilities: one is to
|
|
choose a “physical” representation, another would be a “logical”
|
|
one. The <span style="font-weight: bold">physical</span> representation keeps track of the actual physical
|
|
<span style="font-weight: bold">position</span> of the blocks on the canvas; the <span class="emph">logical</span> one counts
|
|
how many block widths a block is from the left and the top. When it comes
|
|
to the resting blocks, there are even more choices than for individual
|
|
blocks: a list of physical positions, a list of logical positions, a
|
|
list of stack heights, and so forth.</p><p><div class="SIntrapara">In this section we choose the data representation for you:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">tetris</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">block</span><span class="hspace"> </span><span class="RktSym">landscape</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">block</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._tetri)"></a><span style="font-style: italic">Tetris</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-tetris</span><span class="stt"> </span><a href="part_two.html#%28tech._block%29" class="techoutside" data-pltdoc="x"><span class="techinside">Block</span></a><span class="stt"> </span><a href="part_two.html#%28tech._landscape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Landscape</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._landscape)"></a><span style="font-style: italic">Landscape</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._block%29" class="techoutside" data-pltdoc="x"><span class="techinside">Block</span></a><span class="stt"> </span><a href="part_two.html#%28tech._landscape%29" class="techoutside" data-pltdoc="x"><span class="techinside">Landscape</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._block)"></a><span style="font-style: italic">Block</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-block</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="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><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretations</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-block</span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktCmt"> depicts a block whose left </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">corner is </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">SIZE</span><span class="RktPn">)</span><span class="RktCmt"> pixels from the left and</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="stt"> </span><span class="RktSym">y</span><span class="stt"> </span><span class="RktSym">SIZE</span><span class="RktPn">)</span><span class="RktCmt"> pixels from the top;</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym">make-tetris</span><span class="stt"> </span><span class="RktSym">b0</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktSym">b1</span><span class="stt"> </span><span class="RktSym">b2</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktCmt"> means </span><span class="RktSym">b0</span><span class="RktCmt"> is the</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">dropping block, while </span><span class="RktSym">b1</span><span class="RktCmt">, </span><span class="RktSym">b2</span><span class="RktCmt">, and </span>...<span class="RktCmt"> are resting</span></td></tr></table></blockquote></div><div class="SIntrapara">This is what we dubbed the logical representation, because the coordinates
|
|
do not reflect the physical location of the blocks, just the number of
|
|
block sizes they are from the origin. Our choice implies that <span class="RktSym">x</span>
|
|
is always between <span class="RktVal">0</span> and <span class="RktSym">WIDTH</span> (exclusive) and that
|
|
<span class="RktSym">y</span> is between <span class="RktVal">0</span> and <span class="RktSym">HEIGHT</span> (exclusive), but we
|
|
ignore this knowledge.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3atetris0))"></a><span style="font-weight: bold">Exercise</span> 220. When you are presented with a complex data
|
|
definition—<wbr></wbr>like the one for the state of a Tetris game—<wbr></wbr>you start by
|
|
creating instances of the various data collections. Here are some
|
|
suggestive names for examples you can later use for functional 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">landscape0</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">block-dropping</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">tetris0</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">tetris0-drop</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">block-landed</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-block</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">block-on-block</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-block</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">HEIGHT</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>Design the program <span class="RktSym">tetris-render</span>, which turns a given instance of
|
|
<a href="part_two.html#%28tech._tetri%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tetris</span></a> into an <a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a>. Use DrRacket’s interactions area to
|
|
develop the expression that renders some of your (extremely) simple data
|
|
examples. Then formulate the <a name="(idx._(gentag._337))"></a>functional examples as <a name="(idx._(gentag._338))"></a>unit tests and the
|
|
function itself. <a href="part_two.html#%28counter._%28exercise._ex~3atetris0%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3atetris1))"></a><span style="font-weight: bold">Exercise</span> 221. Design the interactive program <span class="RktSym">tetris-main</span>,
|
|
which displays blocks dropping in a straight line from the top of the
|
|
canvas and landing on the floor or on blocks that are already resting. The
|
|
input to <span class="RktSym">tetris-main</span> should determine the rate at which the clock
|
|
ticks. See the documentation of <span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-tick%29%29" class="RktStxLink" data-pltdoc="x">on-tick</a></span> for how to specify the
|
|
rate.</p><p>To discover whether a block landed, we suggest you drop it and check
|
|
whether it is on the floor or it overlaps with one of the blocks on the
|
|
list of resting blocks. <span style="font-weight: bold">Hint</span> Read up on the <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._member~3f%29%29" class="RktValLink" data-pltdoc="x">member?</a></span>
|
|
primitive.</p><p>When a block lands, your program should immediately create another block
|
|
that descends on the column to the right of the current one. If the
|
|
current block is already in the right-most column, the next block should
|
|
use the left-most one. Alternatively, define the function
|
|
<span class="RktSym">block-generate</span>, which randomly selects a column different from
|
|
the current one; see <a href="part_two.html#%28counter._%28exercise._ex~3aworm5%29%29" data-pltdoc="x">exercise 219</a> for inspiration. <a href="part_two.html#%28counter._%28exercise._ex~3atetris1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3atetris2))"></a><span style="font-weight: bold">Exercise</span> 222. Modify the program from <a href="part_two.html#%28counter._%28exercise._ex~3atetris1%29%29" data-pltdoc="x">exercise 221</a> so that
|
|
a player can control the horizontal movement of the dropping
|
|
block. Each time the player presses the <span class="RktVal">"left"</span> arrow key, the
|
|
dropping block should shift one column to the left unless it is in column
|
|
<span class="RktVal">0</span> or there is already a stack of resting blocks to its
|
|
left. Similarly, each time the player presses <span class="RktVal">"right"</span>, the
|
|
dropping block should move one column to the right if possible. <a href="part_two.html#%28counter._%28exercise._ex~3atetris2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3atetris3))"></a><span style="font-weight: bold">Exercise</span> 223. Equip the program from <a href="part_two.html#%28counter._%28exercise._ex~3atetris2%29%29" data-pltdoc="x">exercise 222</a> with a
|
|
<span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._stop-when%29%29" class="RktStxLink" data-pltdoc="x">stop-when</a></span> clause. The game ends when one of the columns contains
|
|
enough blocks to “touch” the top of the canvas. <a href="part_two.html#%28counter._%28exercise._ex~3atetris3%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Once you have solved <a href="part_two.html#%28counter._%28exercise._ex~3atetris3%29%29" data-pltdoc="x">exercise 223</a>, you have a bare-bones Tetris
|
|
game. You may wish to polish it a bit before you show it to your
|
|
friends. For example, the final canvas could display a text that says how
|
|
many blocks the player was able to stack up. Or every canvas could contain
|
|
such a text. The choice is yours.</p><h4>12.7<tt> </tt><a name="(part._sec~3aspace-war)"></a>Full Space War</h4><p><a href="part_one.html#%28part._ch~3amix%29" data-pltdoc="x">Itemizations and Structures</a> alludes to a space invader game with little action; the
|
|
player can merely move the ground force back and
|
|
forth. <a href="part_two.html#%28part._sec~3alist-world%29" data-pltdoc="x">Lists and World</a> enables the player to fire as many shots as
|
|
desired. This section poses exercises that help you complete this game.</p><p>As always, a UFO is trying to land on Earth. The player’s task is to prevent
|
|
the UFO from landing. To this end, the game comes with a tank that may fire
|
|
an arbitrary number of shots. When one of these shots comes close enough to
|
|
the UFO’s center of gravity, the game is over and the player won. If the
|
|
UFO comes close enough to the ground, the player lost.</p><p><a name="(counter._(exercise._ex~3aufo-complete))"></a><span style="font-weight: bold">Exercise</span> 224. Use the lessons learned from the preceding two
|
|
sections and design the game extension slowly, adding one feature of the
|
|
game after another. Always use the design recipe and rely on the
|
|
<a name="(idx._(gentag._339))"></a>guidelines for auxiliary functions. If you like the game, add other
|
|
features: show a running text; equip the UFO with charges that can
|
|
eliminate the tank; create an entire fleet of attacking UFOs; and above
|
|
all, use your imagination. <a href="part_two.html#%28counter._%28exercise._ex~3aufo-complete%29%29" class="ex-end" data-pltdoc="x"></a></p><p>If you don’t like UFOs and tanks shooting at each other, use the same
|
|
ideas to produce a similar, civilized game.</p><p><a name="(counter._(exercise._ex~3afire-fighters))"></a><span style="font-weight: bold">Exercise</span> 225. Design a fire-fighting game.</p><p>The game is set in the western states where fires rage through vast
|
|
forests. It simulates an airborne fire-fighting effort. Specifically, the
|
|
player acts as the pilot of an airplane that drops loads of water on fires
|
|
on the ground. The player controls the plane’s horizontal movements and the
|
|
release of water loads.</p><p>Your game software starts fires at random places on the ground. You may
|
|
wish to limit the number of fires, making them a function of how many
|
|
fires are currently burning or other factors. The purpose of the game is
|
|
to extinguish all fires in a limited amount of time. <span style="font-weight: bold">Hint</span> Use an
|
|
iterative design approach as illustrated in this chapter to create this
|
|
game. <a href="part_two.html#%28counter._%28exercise._ex~3afire-fighters%29%29" class="ex-end" data-pltdoc="x"></a></p><h4>12.8<tt> </tt><a name="(part._sec~3asec-fsm-list)"></a>Finite State Machines</h4><p>Finite state machines (FSMs) and regular expressions are ubiquitous
|
|
elements of programming. As <a href="part_one.html#%28part._sec~3aworlds-more%29" data-pltdoc="x">Finite State Worlds</a> explains,
|
|
state machines are one way to think about world programs. Conversely,
|
|
<a href="part_one.html#%28counter._%28exercise._ex~3afsm%29%29" data-pltdoc="x">exercise 109</a> shows how to design world programs that implement an FSM and
|
|
check whether a player presses a specific series of keystrokes.</p><p><div class="SIntrapara">As you may also recall, a finite state machine is equivalent to a regular
|
|
expression. Hence, computer scientists tend to say that an FSM accepts the
|
|
keystrokes that match a particular regular expression, like this one
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><span class="stt">a (b|c)* d</span></p></blockquote></div><div class="SIntrapara">from <a href="part_one.html#%28counter._%28exercise._ex~3afsm%29%29" data-pltdoc="x">exercise 109</a>. If you wanted a program that recognizes a
|
|
different pattern, say,
|
|
</div><div class="SIntrapara"><blockquote class="SCentered"><p><span class="stt">a (b|c)* a</span></p></blockquote></div><div class="SIntrapara">you would just modify the existing program appropriately. The two programs
|
|
would resemble each other, and if you were to repeat this exercise for
|
|
several different regular expressions, you would end up with a whole
|
|
bunch of similar-looking programs.</div></p><p>A natural idea is to look for a general solution, that is, a world
|
|
program that consumes a <span style="font-weight: bold">data representation of an FSM</span> and
|
|
recognizes whether a player presses a matching sequence of keys. This
|
|
section presents the design of just such a world program, though a greatly
|
|
simplified one. In particular, the FSMs come without initial or final
|
|
states, and the matching ignores the actual keystrokes; instead the transition
|
|
from one state to another takes place whenever <span style="font-weight: bold">any</span> key is pressed. Furthermore,
|
|
we require that the states are color strings. That way, the
|
|
FSM-interpreting program can simply display the current state as a color.</p><p><div class="SIntrapara"><span style="font-weight: bold">Note on Design Choices</span> Here is another attempt to generalize:
|
|
</div><div class="SIntrapara"><blockquote><p><span style="font-weight: bold">Sample Problem</span> Design a program that interprets a given FSM on a specific
|
|
list of <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a>s. That is, the program consumes a data
|
|
representation of an FSM and a string. Its result is <span class="RktVal">#true</span> if the
|
|
string matches the regular expression that corresponds to the FSM;
|
|
otherwise it is <span class="RktVal">#false</span>.</p></blockquote></div><div class="SIntrapara">As it turns out, however, you <span style="font-weight: bold">cannot design</span> this program with the
|
|
principles of the first two parts. Indeed, solving this problem has to wait
|
|
until <a href="part_five.html#%28part._ch~3abacktrack%29" data-pltdoc="x">Algorithms that Backtrack</a>; see <a href="part_five.html#%28counter._fsm._%28exercise._ex~3afsm-match%29%29" data-pltdoc="x">exercise 476</a>. <span style="font-weight: bold">End</span></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"> </span><span class="RktCmt">An </span><a name="(tech._fsm)"></a><span style="font-style: italic">FSM</span><span class="RktCmt"> is one of:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</span></a><span class="stt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">transition</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">current</span><span class="hspace"> </span><span class="RktSym">next</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._transition)"></a><span style="font-style: italic">Transition</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-transition</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><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a name="(tech._fsm._state)"></a><span style="font-style: italic">FSM-State</span><span class="RktCmt"> is a </span><a href="part_one.html#%28tech._data-uni._color%29" class="techoutside" data-pltdoc="x"><span class="techinside">Color</span></a><span class="RktCmt">.</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span style="font-weight: bold">interpretation</span><span class="RktCmt"> An </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> represents the transitions that a</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finite state machine can take from one state to another </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">in reaction to keystrokes </span></td></tr></table></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3afsm1))" x-target-lift="Figure"></a>Figure 82: </span>Representing and interpreting finite state machines in general</span></p></blockquote><p>The simplified problem statement dictates a number of points, including the
|
|
need for a data definition for the representation of FSMs, the nature of
|
|
its states, and their appearance as an image. <a href="part_two.html#%28counter._%28figure._fig~3afsm1%29%29" data-pltdoc="x">Figure <span class="FigureRef">82</span></a>
|
|
collects this information. It starts with a data definition for
|
|
<a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>s. As you can see, an <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> is just a list of
|
|
<a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</span></a>s. We must use a list because we want our world program
|
|
to work with any FSM and that means a finite, but arbitrarily large, number of
|
|
states. Each <a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</span></a> combines two states in a structure: the
|
|
<span class="RktSym">current</span> state and the <span class="RktSym">next</span> state, that is, the one that
|
|
the machine transitions to when the player presses a key. The final part of
|
|
the data definition says that a state is just the name of a color.</p><p><a name="(counter._(exercise._ex~3afsm-state~3d))"></a><span style="font-weight: bold">Exercise</span> 226. Design <span class="RktSym">state=?</span>, an equality predicate
|
|
for states. <a href="part_two.html#%28counter._%28exercise._ex~3afsm-state~3d%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Since this definition is complex, we follow the design recipe and create an 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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-transition</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-transition</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="hspace"> </span><span class="RktVal">"yellow"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-transition</span><span class="hspace"> </span><span class="RktVal">"yellow"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">You probably guessed that this transition table describes a traffic
|
|
light. Its first transition tells us that the traffic light jumps from
|
|
<span class="RktVal">"red"</span> to <span class="RktVal">"green"</span>, the second one represents the
|
|
transition from <span class="RktVal">"green"</span> to <span class="RktVal">"yellow"</span>, and the last one is
|
|
for <span class="RktVal">"yellow"</span> to <span class="RktVal">"red"</span>.</div></p><p><a name="(counter._(exercise._ex~3afsm-design2))"></a><span style="font-weight: bold">Exercise</span> 227. The BW Machine is an FSM that flips from black
|
|
to white and back to black for every key event. Formulate a data
|
|
representation for the BW Machine. <a href="part_two.html#%28counter._%28exercise._ex~3afsm-design2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><div class="SIntrapara">Clearly, the solution to our problem is a world program:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> -> ???</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">match the keys pressed with the given </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">simulate</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">It is supposed to consume a <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>, but we have no clue what the
|
|
program is to produce. We call the program <span class="RktSym">simulate</span> because it
|
|
acts like the given <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> in response to a player’s keystrokes.</div></p><p>Let’s follow the design recipe for world programs anyway to see how far it
|
|
takes us. It tells us to differentiate between those things in
|
|
the “real world” that change and those that remain the same. While the
|
|
<span class="RktSym">simulate</span> function consumes an instance of <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>, we also
|
|
know that this <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> does not change. What changes is the current
|
|
state of the machine.</p><p><div class="SIntrapara">This analysis suggests the following data definition
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._simulationstate..v1)"></a><span style="font-style: italic">SimulationState.v1</span><span class="RktCmt"> is an </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></p></blockquote></div><div class="SIntrapara">According to the design recipe for world programs, this data definition
|
|
completes the main function:<span class="refelem"><span class="refcolumn"><span class="refcontent">The <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>
|
|
constant represents an “invisible” image. It is a good default value for
|
|
writing down the headers of rendering functions.</span></span></span><a name="(idx._(gentag._340))"></a>
|
|
<a name="(idx._(gentag._341))"></a>
|
|
<a name="(idx._(gentag._342))"></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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">simulate.v1</span><span class="hspace"> </span><span class="RktSym">fsm0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktSym">initial-state</span></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">render-state.v1</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state.v1</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">and implies a wish list with two entries:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.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></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders a world state as an image </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-state.v1</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </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><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v1</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._simulationstate..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v1</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the next state from </span><span class="RktSym">ke</span><span class="RktCmt"> and </span><span class="RktSym">cs</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state.v1</span><span class="hspace"> </span><span class="RktSym">cs</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">cs</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The sketch raises two questions. First, there is the issue of how the
|
|
very first <a href="part_two.html#%28tech._simulationstate..v1%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v1</span></a> is determined. Currently, the chosen
|
|
state, <span class="RktSym">initial-state</span>, is marked in grey to warn you about the
|
|
issue. Second, the second entry on the wish list must cause some
|
|
consternation:
|
|
</div><div class="SIntrapara"><blockquote><p>How can <span class="RktSym">find-next-state</span> possibly find the
|
|
next state when all it is given is the current state and a keystroke?</p></blockquote></div><div class="SIntrapara">This question rings especially true because, according to the simplified
|
|
problem statement, the exact nature of the keystroke is
|
|
irrelevant; the FSM transitions to the next state regardless of which key
|
|
is pressed.</div></p><p><div class="SIntrapara">What this second issue exposes is <span style="font-weight: bold">a fundamental limitation of
|
|
BSL+</span>. To appreciate this limitation, we start with a
|
|
work-around. Basically, the analysis demands that the
|
|
<span class="RktSym">find-next-state</span> function receives not only the current state but
|
|
also the <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> so that it can search the list of transitions and pick
|
|
the next state. In other words, the state of the world must include
|
|
both<span class="refelem"><span class="refcolumn"><span class="refcontent">Alonzo Church and Alan Turing, the first two computer
|
|
scientists, proved in the 1930s that all programming languages can compute
|
|
certain functions on numbers. Hence, they argued that all programming
|
|
languages were equal. The first author of this book
|
|
<a href="Https://felleisen.org/matthias/papers.html#scp91-felleisen">disagrees</a>. He
|
|
distinguishes languages according to <span style="font-weight: bold">how</span> they allow programmers to
|
|
express solutions.</span></span></span> the current state of the <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> and the
|
|
<a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> itself:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">fs</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktSym">current</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._simulationstate..v2)"></a><span style="font-style: italic">SimulationState.v2</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="stt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><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="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">According to the world design recipe, this change also means that the
|
|
key-event handler must return this combination: <a name="(idx._(gentag._343))"></a>
|
|
<a name="(idx._(gentag._344))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders a world state as an image </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">render-state.v2</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </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><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the next state from </span><span class="RktSym">ke</span><span class="RktCmt"> and </span><span class="RktSym">cs</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state.v2</span><span class="hspace"> </span><span class="RktSym">cs</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">cs</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Finally, the main function must now consume two arguments: the <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>
|
|
and its first state. After all, the various <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>s that
|
|
<span class="RktSym">simulate</span> consumes come with all kinds of states; we cannot assume
|
|
that all of them have the same initial state. Here is the revised function
|
|
header: <a name="(idx._(gentag._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"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">match the keys pressed with the given </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">simulate.v2</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._big-bang%29%29" class="RktStxLink" data-pltdoc="x">big-bang</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">s0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._to-draw%29%29" class="RktStxLink" data-pltdoc="x">to-draw</a></span><span class="hspace"> </span><span class="RktSym">state-as-colored-square</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpuniverse.html#%28form._world._%28%28lib._2htdp%2Funiverse..rkt%29._on-key%29%29" class="RktStxLink" data-pltdoc="x">on-key</a></span><span class="hspace"> </span><span class="RktSym">find-next-state</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Let’s return to the example of the traffic-light <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>. For this
|
|
machine, it would be best to apply <span class="RktSym">simulate</span> to the machine and
|
|
<span class="RktVal">"red"</span>:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">simulate.v2</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Stop! Why do you think <span class="RktVal">"red"</span> is good for traffic
|
|
lights?<span class="refelem"><span class="refcolumn"><span class="refcontent">Engineers call <span class="RktVal">"red"</span> the <span style="font-weight: bold">safe state</span>.</span></span></span></div></p><p><span style="font-weight: bold">Note on Expressive Power</span> Given the work-around, we can now explain
|
|
the limitation of BSL. Even though the given <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> does not change
|
|
during the course of the simulation, its description must become a part of
|
|
the world’s state. Ideally, the program should express that the description
|
|
of the <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> remains constant, but instead the program must treat the
|
|
<a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> as part of the ever-changing state. The reader of a program
|
|
cannot deduce this fact from the first piece of <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> alone.</p><p>The next part of the book resolves this conundrum with the introduction of
|
|
a new programming language and a specific linguistic construct: ISL and
|
|
<span class="RktSym">local</span> definitions. For details, see <a href="part_three.html#%28part._sec~3alocal-is-power%29" data-pltdoc="x">Local Definitions Add Expressive Power</a>.
|
|
<span style="font-weight: bold">End</span></p><p><div class="SIntrapara">At this point, we can turn to the wish list and work through its
|
|
entries, one at a time. The first one, the design of
|
|
<span class="RktSym">state-as-colored-square</span>, is so straightforward that we simply
|
|
provide the complete definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a><span class="RktCmt"> -> </span><a href="part_one.html#%28tech._image%29" class="techoutside" data-pltdoc="x"><span class="techinside">Image</span></a><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">renders current world state as a colored square </span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">state-as-colored-square</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._square%29%29" class="RktValLink" data-pltdoc="x">square</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">state-as-colored-square</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._square%29%29" class="RktValLink" data-pltdoc="x">square</a></span><span class="hspace"> </span><span class="RktVal">100</span><span class="hspace"> </span><span class="RktVal">"solid"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-current</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><a name="(idx._(gentag._346))"></a></div></p><p><div class="SIntrapara">In contrast, the design of the key-event handler deserves some
|
|
discussion. Recall the header material: <a name="(idx._(gentag._347))"></a>
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the next state from </span><span class="RktSym">an-fsm</span><span class="RktCmt"> and </span><span class="RktSym">ke</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">According to the design recipe, the handler must consume a state of the
|
|
world and a <a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a>, and it must produce the next state of the
|
|
world. This articulation of the signature in plain words also guides the
|
|
design of examples. Here are the first two:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"n"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"a"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The examples say that when the current state combines the <span class="RktSym">fsm-traffic</span>
|
|
machine and its <span class="RktVal">"red"</span> state, the result combines the same
|
|
<a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> with <span class="RktVal">"green"</span>, regardless of whether the
|
|
player hit <span class="RktVal">"n"</span> or <span class="RktVal">"a"</span> on the keyboard. Here is one more
|
|
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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"q"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"yellow"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Interpret the example before reading on. Can you think of another one?</div></p><p><div class="SIntrapara">Since the function consumes a structure, we write down a template for
|
|
structures processing:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-fsm</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._....%29%29" class="RktStxLink" data-pltdoc="x">..</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-current</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">Furthermore, because the desired result is a <a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a>,
|
|
we can refine the template with the addition of an appropriate
|
|
constructor:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-fsm</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-current</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..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">The examples suggest that the extracted <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> becomes the first
|
|
component of the new <a href="part_two.html#%28tech._simulationstate..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">SimulationState.v2</span></a> and that the function
|
|
really just needs to compute the next state from the current one and the
|
|
list of <a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</span></a>s that make up the given <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>. Because the
|
|
latter is arbitrarily long, we make up a wish—<wbr></wbr>a <span class="RktSym">find</span> function
|
|
that traverses the list to look for a <a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</span></a> whose
|
|
current state is <span class="RktPn">(</span><span class="RktSym">fs-current</span><span class="stt"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span>—<wbr></wbr>and finish the
|
|
definition:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find-next-state</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="hspace"> </span><span class="RktSym">ke</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fs</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-fsm</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-fsm</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fs-current</span><span class="hspace"> </span><span class="RktSym">an-fsm</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Here is the formulation of the new wish:
|
|
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a><span class="RktCmt"> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a><span class="RktCmt"> -> </span><a href="part_two.html#%28tech._fsm._state%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM-State</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">finds the state representing </span><span class="RktSym">current</span><span class="RktCmt"> in </span><span class="RktSym">transitions</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">and retrieves the </span><span class="RktSym">next</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"red"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"green"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"green"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"yellow"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._check-error%29%29" class="RktStxLink" data-pltdoc="x">check-error</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">fsm-traffic</span><span class="hspace"> </span><span class="RktVal">"black"</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"not found: black"</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">find</span><span class="hspace"> </span><span class="RktSym">transitions</span><span class="hspace"> </span><span class="RktSym">current</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">current</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara"><a name="(idx._(gentag._348))"></a>
|
|
The examples are derived from the examples for
|
|
<span class="RktSym">find-next-state</span>.</div></p><p>Stop! Develop some additional examples, then tackle the exercises.</p><p><a name="(counter._(exercise._ex~3afsm0))"></a><span style="font-weight: bold">Exercise</span> 228. Complete the design of <span class="RktSym">find</span>.</p><p>Once the auxiliary functions are tested, use <span class="RktSym">simulate</span> to play
|
|
with <span class="RktSym">fsm-traffic</span> and the BW Machine from <a href="part_two.html#%28counter._%28exercise._ex~3afsm-design2%29%29" data-pltdoc="x">exercise 227</a>. <a href="part_two.html#%28counter._%28exercise._ex~3afsm0%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Our simulation program is intentionally quite restrictive. In particular,
|
|
you cannot use it to represent <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>s that transition from
|
|
one state to another depending on which key a player presses. Given the
|
|
systematic design, though, you can extend the program with such capabilities.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afsm-design3))"></a><span style="font-weight: bold">Exercise</span> 229. Here is a revised data definition for
|
|
<a href="part_two.html#%28tech._transition%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">ktransition</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">current</span><span class="hspace"> </span><span class="RktSym">key</span><span class="hspace"> </span><span class="RktSym">next</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._transition..v2)"></a><span style="font-style: italic">Transition.v2</span><span class="RktCmt"> is a structure:</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-ktransition</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><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><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="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Represent the FSM from <a href="part_one.html#%28counter._%28exercise._ex~3afsm%29%29" data-pltdoc="x">exercise 109</a> using lists of <a href="part_two.html#%28tech._transition..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition.v2</span></a>s;
|
|
ignore errors and final states.</div></p><p>Modify the design of <span class="RktSym">simulate</span> so that it deals with keystrokes in
|
|
the appropriate manner now. Follow the design recipe, starting with the
|
|
adaptation of the data examples.</p><p>Use the revised program to simulate a run of the FSM from <a href="part_one.html#%28counter._%28exercise._ex~3afsm%29%29" data-pltdoc="x">exercise 109</a> on
|
|
the following sequence of keystrokes: <span class="RktVal">"a"</span>, <span class="RktVal">"b"</span>,
|
|
<span class="RktVal">"b"</span>, <span class="RktVal">"c"</span>, and <span class="RktVal">"d"</span>. <a href="part_two.html#%28counter._%28exercise._ex~3afsm-design3%29%29" class="ex-end" data-pltdoc="x"></a></p><p>Finite state machines do come with initial and final states. When a program
|
|
that “runs” an <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a> reaches a final state, it should
|
|
stop. The final exercise revises the data representation of <a href="part_two.html#%28tech._fsm%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM</span></a>s one
|
|
more time to introduce these ideas.</p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3afsm-list))"></a><span style="font-weight: bold">Exercise</span> 230. Consider the following data representation for FSMs:
|
|
</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">fsm</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">initial</span><span class="hspace"> </span><span class="RktSym">transitions</span><span class="hspace"> </span><span class="RktSym">final</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/beginner.html#%28form._%28%28lib._lang%2Fhtdp-beginner..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">transition</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">current</span><span class="hspace"> </span><span class="RktSym">key</span><span class="hspace"> </span><span class="RktSym">next</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">An </span><a name="(tech._fsm..v2)"></a><span style="font-style: italic">FSM.v2</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-fsm</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><a href="part_two.html#%28tech._lot%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOT</span></a><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="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._lot)"></a><span style="font-style: italic">LOT</span><span class="RktCmt"> is one of: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktCmt"> </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">–</span><span class="RktCmt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/beginner.html#%28def._htdp-beginner._%28%28lib._lang%2Fhtdp-beginner..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="stt"> </span><a href="part_two.html#%28tech._transition..v3%29" class="techoutside" data-pltdoc="x"><span class="techinside">Transition.v3</span></a><span class="stt"> </span><a href="part_two.html#%28tech._lot%29" class="techoutside" data-pltdoc="x"><span class="techinside">LOT</span></a><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">A </span><a name="(tech._transition..v3)"></a><span style="font-style: italic">Transition.v3</span><span class="RktCmt"> is a structure: </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-transition</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><a href="part_one.html#%28tech._keyevent%29" class="techoutside" data-pltdoc="x"><span class="techinside">KeyEvent</span></a><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="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Represent the FSM from <a href="part_one.html#%28counter._%28exercise._ex~3afsm%29%29" data-pltdoc="x">exercise 109</a> in this context.</div></p><p>Design the function <span class="RktSym">fsm-simulate</span>, which accepts an <a href="part_two.html#%28tech._fsm..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM.v2</span></a>
|
|
and runs it on a player’s keystrokes. If the sequence of keystrokes forces
|
|
the <a href="part_two.html#%28tech._fsm..v2%29" class="techoutside" data-pltdoc="x"><span class="techinside">FSM.v2</span></a> to reach a final state, <span class="RktSym">fsm-simulate</span> stops.
|
|
<span style="font-weight: bold">Hint</span> The function uses the <span class="RktSym">initial</span> field of the given
|
|
<span class="RktSym">fsm</span> structure to track the current state. <a href="part_two.html#%28counter._%28exercise._ex~3afsm-list%29%29" class="ex-end" data-pltdoc="x"></a></p><p><span style="font-weight: bold">Note on Iterative Refinement</span> These last two projects introduce the
|
|
notion of <a name="(idx._(gentag._349))"></a>“design by iterative refinement.” The basic idea is that the
|
|
first program implements only a fraction of the desired behavior, the next
|
|
one a bit more, and so on. Eventually you end up with a program that
|
|
exhibits all of the desired behavior, or at least enough of it to satisfy a
|
|
customer. For more details, see <a href="part_four.html#%28part._ch~3afiles%29" data-pltdoc="x">Iterative Refinement</a>. <span style="font-weight: bold">End</span></p><h3>13<tt> </tt><a name="(part._ch~3asummary2)"></a>Summary</h3><p>This second part of the book is about the design of programs that deal with
|
|
arbitrarily large data. As you can easily imagine, software is
|
|
particularly useful when it is used on information that comes without
|
|
prespecified size limits, meaning “arbitrarily large data” is a
|
|
critical step on your way to becoming a real programmer. In this spirit,
|
|
we suggest that you take away three lessons:</p><p><div class="SIntrapara"><ol><li><p>This part <span style="font-weight: bold">refines the design recipe</span> to deal with
|
|
self-references and cross-references in data definitions. The occurrence
|
|
of the former calls for the design of recursive functions, and the
|
|
occurrence of the latter calls for auxiliary functions.</p></li><li><p>Complex problems call for a <span style="font-weight: bold">decomposition</span> into separate
|
|
problems. When you decompose a problem, you need two pieces: functions
|
|
that solve the separate problems and data definitions that compose these
|
|
separate solutions into a single one. To ensure that the composition works
|
|
after you have spent time on the separate programs, you need to
|
|
formulate your “wishes” together with the required data definitions.</p><p>A decomposition-composition design is especially useful when the problem
|
|
statement implicitly or explicitly mentions auxiliary tasks, when the
|
|
coding step for a function calls for a traversal of an(other) arbitrarily
|
|
large piece of data, and—<wbr></wbr>perhaps surprisingly—<wbr></wbr>when a general problem
|
|
is somewhat easier to solve than the specific one described in the problem
|
|
statement.</p></li><li><p><span style="font-weight: bold">Pragmatics matter.</span> If you wish to design <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>
|
|
programs, you need to understand its various clauses and what they
|
|
accomplish. Or, if your task is to design programs that solve mathematical
|
|
problems, you had better make sure you know which mathematical operations the
|
|
chosen language and its libraries offer.</p></li></ol></div><div class="SIntrapara">While this part mostly focuses on lists as a good example of arbitrarily
|
|
large data—<wbr></wbr>because they are practically useful in languages such as
|
|
Haskell, Lisp, ML, Racket, and Scheme—<wbr></wbr>the ideas apply to all kinds of
|
|
such data: files, file folders, databases, and the like.</div></p><p><a href="part_four.html" data-pltdoc="x">Intertwined Data</a> continues the exploration of “large” structured data and
|
|
demonstrates how the design recipe scales to the most complex kind of
|
|
data. In the meantime, the next part takes care of an important worry you
|
|
should have at this point, namely, that a programmer’s work is all about
|
|
creating the same kind of programs over and over and over again.</p><div class="navsetbottom"><span class="navleft"><div class="nosearchform"></div> <span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="i1-2.html" title="backward to "Intermezzo 1: Beginning Student Language"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "How to Design Programs, Second Edition"" data-pltdoc="x">up</a> <a href="i2-3.html" title="forward to "Intermezzo 2: Quote, Unquote"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html> |