Lists

#drnseclistslong#9141> external ~<#70949#>The operation <#62011#><#9143#>cons<#9143#><#62011#> is the analogue of enumeration in arithmetic. The most basic action of arithmetic is counting. When we count, we enumerate the numbers starting at 1 and continue with 2, 3, <#9144#>etc<#9144#>. In a sense, counting <#9145#>creates<#9145#> the numbers by adding 1 to 1, then 1 to 2, 1 to 3, <#9146#>etc<#9146#>. Similarly, all lists in Scheme are created with <#62012#><#9147#>cons<#9147#><#62012#>, starting from <#62013#><#9148#>empty<#9148#><#62013#>. The difference is that we do not have short names for <#62014#><#9149#>cons<#9149#><#62014#>tructed lists. Thus, instead of saying <#62015#><#9150#>(+<#9150#>\ <#9151#>1<#9151#>\ <#9152#>1)<#9152#><#62015#>, we say 2. In contrast, list values like <#62016#><#9153#>(cons<#9153#>\ <#9154#>1<#9154#>\ <#9155#>empty)<#9155#><#62016#> are less common in daily life (and are more complex), so we don't have short names for <#62017#><#9156#>cons<#9156#><#62017#>tructed lists. We use the parenthesized expressions as their names instead.<#70949#> When we form a list, we always start out with the empty list. In Scheme, the word <#62018#><#9157#>empty<#9157#><#62018#> represents the empty list. When we already have a list, we can construct a longer list with the operation <#62019#><#9158#>cons<#9158#><#62019#>. Here is a simple example:
<#9163#>(cons<#9163#> <#9164#>'<#9164#><#9165#>Mercury<#9165#> <#9166#>empty)<#9166#> 
In this example, we <#62020#><#9170#>cons<#9170#><#62020#>tructed a list from the <#62021#><#9171#>empty<#9171#><#62021#> list and the symbol <#62022#><#9172#>'<#9172#><#9173#>Mercury<#9173#><#62022#>. Figure~#figbuildalist#9174> depicts this list in a pictorial manner, as a box with two fields: <#62023#><#9175#>first<#9175#><#62023#> and <#62024#><#9176#>rest<#9176#><#62024#>. In this specific example the <#62025#><#9177#>first<#9177#><#62025#> field contains <#62026#><#9178#>'<#9178#><#9179#>Mercury<#9179#><#62026#> and the <#62027#><#9180#>rest<#9180#><#62027#> field contains <#62028#><#9181#>empty<#9181#><#62028#>.
rawhtml19 <#9182#>Figure: Building a list<#9182#>
Once we have a list with one item on it, we can <#62029#><#9184#>cons<#9184#><#62029#>truct lists with two items by using <#62030#><#9185#>cons<#9185#><#62030#> again:
<#9190#>(cons<#9190#> <#9191#>'<#9191#><#9192#>Venus<#9192#> <#9193#>(cons<#9193#> <#9194#>'<#9194#><#9195#>Mercury<#9195#> <#9196#>empty))<#9196#>
The middle row of figure~#figbuildalist#9200> shows how we should imagine the second list. It is also a box of two fields, but this time the <#62031#><#9201#>rest<#9201#><#62031#> field contains a box. Indeed, it contains the box from the top row of the same figure. Finally, we construct a list with three items:
<#9206#>(cons<#9206#> <#9207#>'<#9207#><#9208#>Earth<#9208#> <#9209#>(cons<#9209#> <#9210#>'<#9210#><#9211#>Venus<#9211#> <#9212#>(cons<#9212#> <#9213#>'<#9213#><#9214#>Mercury<#9214#> <#9215#>empty)))<#9215#>
The last row of figure~#figbuildalist#9219> illustrates the list with three items. Its <#62032#><#9220#>rest<#9220#><#62032#> field contains a box that contains a box again. So, as we create lists we put boxes into boxes into boxes <#9221#>etc<#9221#>. While this may appear strange at first glance, it is nothing different than the Chinese gift boxes or the nested drinking cups we get for our early birthdays. The only difference is that we can nest lists much deeper than any artist could nest physical boxes.
<#9224#>Exercise 9.1.1<#9224#> Create Scheme lists that represent
  1. the list of all planets in our solar system;
  2. the following meal: steak, pommes-frites, beans, bread, water, juice brie cheese, and ice-cream;
  3. and the list of basic colors.
Sketch box representations of these lists, similar to those in figure~#figbuildalist#9228>.~ external Solution<#62033#><#62033#>
We can also make lists of numbers. As before, <#62034#><#9236#>empty<#9236#><#62034#> is the list without any items. Here is a list with 10 numbers:
<#9241#>(c<#9241#><#9242#>ons<#9242#> <#9243#>0<#9243#>
  <#9244#>(c<#9244#><#9245#>ons<#9245#> <#9246#>1<#9246#> 
    <#9247#>(c<#9247#><#9248#>ons<#9248#> <#9249#>2<#9249#> 
      <#9250#>(c<#9250#><#9251#>ons<#9251#> <#9252#>3<#9252#> 
        <#9253#>(c<#9253#><#9254#>ons<#9254#> <#9255#>4<#9255#> 
          <#9256#>(c<#9256#><#9257#>ons<#9257#> <#9258#>5<#9258#> 
            <#9259#>(c<#9259#><#9260#>ons<#9260#> <#9261#>6<#9261#> 
              <#9262#>(c<#9262#><#9263#>ons<#9263#> <#9264#>7<#9264#> 
                <#9265#>(c<#9265#><#9266#>ons<#9266#> <#9267#>8<#9267#> 
                  <#9268#>(cons<#9268#> <#9269#>9<#9269#> <#9270#>empty))))))))))<#9270#> 
To build it requires 10 <#62035#><#9274#>cons<#9274#><#62035#>es and one <#62036#><#9275#>empty<#9275#><#62036#>. In general a list does not have to contain values of one kind, but may contain arbitrary values:
<#9280#>(c<#9280#><#9281#>ons<#9281#> <#9282#>'<#9282#><#9283#>RobbyRound<#9283#>
  <#9284#>(c<#9284#><#9285#>ons<#9285#> <#9286#>3<#9286#> 
    <#9287#>(c<#9287#><#9288#>ons<#9288#> <#9289#>true<#9289#> 
      <#9290#>empty)))<#9290#> 
Here the first item is a symbol, the second one is a number, and the last one a Boolean. We could think of this list as the representation of a personnel record that includes the name of the employee, the number of years spent at the company, and whether the employee has health insurance through the company plan. Now suppose we are given a list of numbers. One thing we might wish to do is add up the numbers on the list. To make this more concrete, let us assume that we are only interested in lists of three numbers:
A <#62037#><#9295#>list-of-3-numbers<#9295#><#62037#> is

<#70950#> <#62038#><#9296#>(cons<#9296#>\ <#9297#>x<#9297#>\ <#9298#>(cons<#9298#>\ <#9299#>y<#9299#>\ <#9300#>(cons<#9300#>\ <#9301#>z<#9301#>\ <#9302#>empty)))<#9302#><#62038#> <#70950#> where <#62039#><#9303#>x<#9303#><#62039#>, <#62040#><#9304#>y<#9304#><#62040#>, and <#62041#><#9305#>z<#9305#><#62041#> are numbers.

We write down the contract, purpose, header, and examples as before:
<#70951#>;; <#62042#><#9311#>add-up-3<#9311#> <#9312#>:<#9312#> <#9313#>list-of-3-numbers<#9313#> <#9314#><#9314#><#9315#>-;SPMgt;<#9315#><#9316#><#9316#> <#9317#>number<#9317#><#62042#><#70951#>
<#70952#>;; to add up the three numbers in <#62043#><#9318#>a-list-of-3-numbers<#9318#><#62043#><#70952#> 
<#9319#>;; examples: <#9319#> 
<#70953#>;; <#62044#><#9320#>(add-up-3<#9320#> <#9321#>(cons<#9321#> <#9322#>2<#9322#> <#9323#>(cons<#9323#> <#9324#>1<#9324#> <#9325#>(cons<#9325#> <#9326#>3<#9326#> <#9327#>empty))))<#9327#> <#9328#>=<#9328#> <#9329#>6<#9329#><#62044#><#70953#> 
<#70954#>;; <#62045#><#9330#>(add-up-3<#9330#> <#9331#>(cons<#9331#> <#9332#>0<#9332#> <#9333#>(cons<#9333#> <#9334#>1<#9334#> <#9335#>(cons<#9335#> <#9336#>0<#9336#> <#9337#>empty))))<#9337#> <#9338#>=<#9338#> <#9339#>1<#9339#><#62045#><#70954#> 
<#9340#>(define<#9340#> <#9341#>(add-up-3<#9341#> <#9342#>a-list-of-3-numbers)<#9342#> <#9343#>...)<#9343#> 
To define the body, however, presents a problem. A <#62046#><#9347#>cons<#9347#><#62046#>tructed list is like a structure. Hence, we should layout a template with selector expressions next. Unfortunately, we don't know how to select items from a list. In analogy to structure selectors, Scheme implements operations for extracting the fields from a <#62047#><#9348#>cons<#9348#><#62047#>tructed list: <#62048#><#9349#>first<#9349#><#62048#> and <#62049#><#9350#>rest<#9350#><#62049#>. The <#62052#><#9353#>first<#9353#><#62052#> operation extracts the item that we used to <#62053#><#9354#>cons<#9354#><#62053#>truct a list; the <#62054#><#9355#>rest<#9355#><#62054#> operation extracts the list field. To describe how <#62055#><#9356#>first<#9356#><#62055#>, <#62056#><#9357#>rest<#9357#><#62056#>, and <#62057#><#9358#>cons<#9358#><#62057#> are related, we can use equations that are similar to the equations that govern addition and subtraction and structure creation and field extraction:
  <#72331#>#tex2html_wrap_inline72946#<#72331#>
<#9367#>=<#9367#> <#9368#>10<#9368#> 
  <#72332#>#tex2html_wrap_inline72948#<#72332#> 
<#9373#>=<#9373#> <#9374#>empty<#9374#> 
  <#9375#>(first<#9375#> <#72333#>#tex2html_wrap_inline72950#<#72333#><#9382#>)<#9382#> 
<#9383#>=<#9383#> <#72334#>#tex2html_wrap_inline72952#<#72334#> 
<#9388#>=<#9388#> <#9389#>22<#9389#> 
The last one demonstrates how to evaluate nested expressions. The key is to think of <#62062#><#9393#>(cons<#9393#>\ <#9394#>a-value<#9394#>\ <#9395#>a-list)<#9395#><#62062#> as a value. And, as always, we start with the evaluation of the innermost parenthesized expressions that can be reduced, just as in arithmetic. In the above calculations, the expressions that are about to be reduced next are underlined. Using <#62063#><#9396#>first<#9396#><#62063#> and <#62064#><#9397#>rest<#9397#><#62064#> we can now write down a template for <#62065#><#9398#>add-up-3<#9398#><#62065#>:
<#70960#>;; <#62066#><#9403#>add-up-3<#9403#> <#9404#>:<#9404#> <#9405#>list-of-3-numbers<#9405#> <#9406#><#9406#><#9407#>-;SPMgt;<#9407#><#9408#><#9408#> <#9409#>number<#9409#><#62066#><#70960#>
<#70961#>;; to add up the three numbers in <#62067#><#9410#>a-list-of-3-numbers<#9410#><#62067#><#70961#> 
<#9411#>(d<#9411#><#9412#>efine<#9412#> <#9413#>(add-up-3<#9413#> <#9414#>a-list-of-3-numbers)<#9414#> 
  <#9415#>...<#9415#> <#9416#>(first<#9416#> <#9417#>a-list-of-3-numbers)<#9417#> <#9418#>...<#9418#> 
  <#9419#>...<#9419#> <#9420#>(first<#9420#> <#9421#>(rest<#9421#> <#9422#>a-list-of-3-numbers))<#9422#> <#9423#>...<#9423#> 
  <#9424#>...<#9424#> <#9425#>(first<#9425#> <#9426#>(rest<#9426#> <#9427#>(rest<#9427#> <#9428#>a-list-of-3-numbers)))<#9428#> <#9429#>...<#9429#> <#9430#>)<#9430#> 
The three expressions remind us that the input, called <#62068#><#9434#>a-list-of-3-numbers<#9434#><#62068#>, contains three components and how to extract them.
<#9437#>Exercise 9.1.2<#9437#> Let <#62069#><#9439#>l<#9439#><#62069#> be the list
<#9444#>(cons<#9444#> <#9445#>10<#9445#> <#9446#>(cons<#9446#> <#9447#>20<#9447#> <#9448#>(cons<#9448#> <#9449#>5<#9449#> <#9450#>empty)))<#9450#>
What are the values of the following expressions?
  1. <#62070#><#9455#>(rest<#9455#>\ <#9456#>l)<#9456#><#62070#>
  2. <#62071#><#9457#>(first<#9457#>\ <#9458#>(rest<#9458#>\ <#9459#>l))<#9459#><#62071#>
  3. <#62072#><#9460#>(rest<#9460#>\ <#9461#>(rest<#9461#>\ <#9462#>l))<#9462#><#62072#>
  4. <#62073#><#9463#>(first<#9463#>\ <#9464#>(rest<#9464#>\ <#9465#>(rest<#9465#>\ <#9466#>l)))<#9466#><#62073#>
  5. <#62074#><#9467#>(rest<#9467#>\ <#9468#>(rest<#9468#>\ <#9469#>(rest<#9469#>\ <#9470#>l)))<#9470#><#62074#> external Solution<#62075#><#62075#>
<#9477#>Exercise 9.1.3<#9477#> Finish the development of <#62076#><#9479#>add-up-3<#9479#><#62076#>, that is, define the body and test the complete function on some examples. A list of three numbers is one possible representation for 3-dimensional points. The distance of a 3-dimensional point to the origin of the coordinate grid is computed in the same manner as that of 2-dimensional point: by squaring the numbers, adding them up, and taking the square root. Use the template for <#62077#><#9480#>add-up-3<#9480#><#62077#> to develop <#62078#><#9481#>distance-to-0-for-3<#9481#><#62078#>, which computes the distance of a 3-dimensional point to the origin.~ external Solution<#62079#><#62079#> <#9487#>Exercise 9.1.4<#9487#> Provide a data definition for lists of two symbols. Then develop the function <#62080#><#9489#>contains-2-doll?<#9489#><#62080#>, which consumes a list of two symbols and determines whether one of them is <#62081#><#9490#>'<#9490#><#9491#>doll<#9491#><#62081#>.~ external Solution<#62082#><#62082#>

<#9499#>On the Precise Relationship between Cons and Structures<#9499#>:\ The discussion of <#62083#><#9500#>cons<#9500#><#62083#>, <#62084#><#9501#>first<#9501#><#62084#>, and <#62085#><#9502#>rest<#9502#><#62085#> suggests that <#62086#><#9503#>cons<#9503#><#62086#> creates a structure and <#62087#><#9504#>first<#9504#><#62087#> and <#62088#><#9505#>rest<#9505#><#62088#> are ordinary selectors:

<#9510#>(define-struct<#9510#> <#9511#>pair<#9511#> <#9512#>(left<#9512#> <#9513#>right))<#9513#>
<#9514#>(define<#9514#> <#9515#>(our-cons<#9515#> <#9516#>a-value<#9516#> <#9517#>a-list)<#9517#> <#9518#>(make-pair<#9518#> <#9519#>a<#9519#> <#9520#>d))<#9520#> 
<#9521#>(define<#9521#> <#9522#>(our-first<#9522#> <#9523#>a-pair)<#9523#> <#9524#>(pair-left<#9524#> <#9525#>a-pair))<#9525#> 
<#9526#>(define<#9526#> <#9527#>(our-rest<#9527#> <#9528#>a-pair)<#9528#> <#9529#>(pair-right<#9529#> <#9530#>a-pair))<#9530#> 
<#9531#>(define<#9531#> <#9532#>(our-cons?<#9532#> <#9533#>x)<#9533#> <#9534#>(pair?<#9534#> <#9535#>x))<#9535#> 
Although these definitions are a good first approximation, they are inaccurate in one important point. DrScheme's version of <#62089#><#9539#>cons<#9539#><#62089#> is really a checked version of <#62090#><#9540#>make-pair<#9540#><#62090#>. Specifically, the <#62091#><#9541#>cons<#9541#><#62091#> operation ensures that the <#62092#><#9542#>right<#9542#><#62092#> field is always a list, <#9543#>i.e.<#9543#>, <#62093#><#9544#>cons<#9544#><#62093#>tructed or <#62094#><#9545#>empty<#9545#><#62094#>. This suggests the following refinement:
<#9550#>(d<#9550#><#9551#>efine<#9551#> <#9552#>(our-cons<#9552#> <#9553#>a-value<#9553#> <#9554#>a-list)<#9554#>
  <#9555#>(c<#9555#><#9556#>ond<#9556#> 
    <#9557#>[<#9557#><#9558#>(empty?<#9558#> <#9559#>a-list)<#9559#> <#9560#>(make-pair<#9560#> <#9561#>any<#9561#> <#9562#>a-list)]<#9562#> 
    <#9563#>[<#9563#><#9564#>(our-cons?<#9564#> <#9565#>a-list)<#9565#> <#9566#>(make-pair<#9566#> <#9567#>any<#9567#> <#9568#>a-list)]<#9568#> 
    <#9569#>[<#9569#><#9570#>else<#9570#> <#9571#>(error<#9571#> <#9572#>'<#9572#><#9573#>cons<#9573#> <#9574#>``list<#9574#> <#9575#>as<#9575#> <#9576#>second<#9576#> <#9577#>argument<#9577#> <#9578#>expected'')]<#9578#><#9579#>))<#9579#> 
The definitions for <#62095#><#9583#>our-first<#9583#><#62095#>, <#62096#><#9584#>our-rest<#9584#><#62096#>, and <#62097#><#9585#>our-cons?<#9585#><#62097#> remain the same. Finally, we must also promised not to use <#62098#><#9586#>make-pair<#9586#><#62098#> directly so that we don't accidentally build a bad list.~<#62099#><#62099#>