Intermediate Student |
Using cons to create lists is cumbersome if a list
contains many items. Fortunately, Scheme provides the list operation, which consumes an arbitrary number of values and
creates a list. Here is Scheme's extended syntax:
<prm> = list
The extended collection of values is
<val> = (list <val> ... <val>)
A simpler way to understand list expressions is to think
of them as abbreviations. Specifically, every expression of the
shape
(list exp-1 ... exp-n)
stands for a series of n cons expressions:
(cons exp-1 (cons ... (cons exp-n empty)))
Recall that empty is not an item of the list here, but the rest of
the list. Here are three examples:
(list 1 2) = (cons 1 (cons 2 empty)) (list 'Houston 'Dallas 'SanAntonio) = (cons 'Houston (cons 'Dallas (cons 'SanAntonio empty))) (list false true false false) = (cons false (cons true (cons false (cons false empty))))
They introduce lists with two, three, and four items, respectively.
Of course, we can apply list not only to values but also
to expressions:
(list (+ 0 1) (+ 1 1)) = (list 1 2)
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:
(list (/ 1 0) (+ 1 1)) = /: divide by zero
In short, list behaves just like any other primitive operation.
The use of list greatly simplifies the notation for lists
with many items and lists that contains lists or structures. Here
is an example:
(list 0 1 2 3 4 5 6 7 8 9)
This list contains 10 items and its formation with cons
and empty would require 10 uses of cons and one
instance of empty. Similarly, the list
(list (list 'bob 0 'a) (list 'carl 1 'a) (list 'dana 2 'b) (list 'erik 3 'c) (list 'frank 4 'a) (list 'grant 5 'b) (list 'hank 6 'c) (list 'ian 8 'a) (list 'john 7 'd) (list 'karel 9 'e))
requires 11 uses of list in contrast to 40 of cons and 11
of empty.
Exercise 13.0.3.
Use cons and empty to construct the equivalent of the
following lists:
(list 0 1 2 3 4 5)
(list (list 'adam 0) (list 'eve 1) (list 'louisXIV 2))
(list 1 (list 1 2) (list 1 2 3)).
Exercise 13.0.4.
Use list to construct the equivalent of the following lists:
(cons 'a (cons 'b (cons 'c (cons 'd (cons 'e empty)))))
(cons (cons 1 (cons 2 empty)) empty)
(cons 'a (cons (cons 1 empty) (cons false empty))).
(cons (cons 1 (cons 2 empty)) (cons (cons 2 (cons 3 empty)) empty))
Start by determining how many items each list and each nested list
contains.
Solution
Exercise 13.0.5.
On rare occasions, we encounter lists formed with cons and
list. Reformulate the following lists using cons and
empty exclusively:
(cons 'a (list 0 false))
(list (cons 1 (cons 13 empty)))
(list empty empty (cons 1 empty))
(cons 'a (cons (list 1) (list false empty))).
Then formulate the lists using list.
Solution
Exercise 13.0.6. Determine the values of the following expressions:
(list (symbol=? 'a 'b) (symbol=? 'c 'c) false)
(list (+ 10 20) (* 10 20) (/ 10 20))
(list 'dana 'jane 'mary 'laura)
Exercise 13.0.7. Determine the values of
(first (list 1 2 3)) (rest (list 1 2 3))
The use of list makes it significantly easier to evaluate
expressions involving lists. Here are the recursive steps from an example
from section 9.5:
(sum (list (make-ir 'robot 22.05) (make-ir 'doll 17.95))) = (+ (ir-price (first (list (make-ir 'robot 22.05) (make-ir 'doll 17.95)))) (sum (rest (list (make-ir 'robot 22.05) (make-ir 'doll 17.95))))) = (+ (ir-price (make-ir 'robot 22.05)) (sum (list (make-ir 'doll 17.95)))) At this place, we use one of the equations governing the new primitive operations for the first time: = (+ 22.05 (sum (list (make-ir 'doll 17.95)))) = (+ 22.05 (+ (ir-price (first (list (make-ir 'doll 17.95)))) (sum (rest (list (make-ir 'doll 17.95)))))) = (+ 22.05 (+ (ir-price (make-ir 'doll 17.95)) (sum empty))) = (+ 22.05 (+ 17.95 (sum empty))) = (+ 22.05 (+ 17.95 0))
Since the laws of first and rest carry over to
list values in a natural manner, an evaluation using list
does not need to expand list into uses of cons and
empty.
Following an old programming language
convention,39 we may abbreviate lists and symbols even further. If a list is
formulated with list, we can simply agree to drop list and that
each opening parenthesis stands for itself and the word list. For
example,
'(1 2 3) abbreviates (list 1 2 3) or (cons 1 (cons 2 (cons 3 empty))) .
Similarly,
'((1 2) (3 4) (5 6)) stands for (list (list 1 2) (list 3 4) (list 5 6)),
which can be further expanded into cons and empty
expressions.
If we drop quotes in front of symbols, writing lists of symbols is a breeze:
'(a b c) This short-hand is an abbreviation for (list 'a 'b 'c)
And, more impressively,
'(<html> (<title> My First Web Page) (<body> Oh!)) stands for (list '<html> (list '<title> 'My 'First 'Web 'Page) (list '<body> 'Oh!)) .
Exercise 13.0.8.
Restore list and quotes where necessary:
'(1 a 2 b 3 c)
'((alan 1000) (barb 2000) (carl 1500) (dawn 2300))
'((My First Paper) (Sean Fisler) (Section 1 (Subsection 1 Life is difficult) (Subsection 2 But learning things makes it interesting)) (Section 2 Conclusion? What conclusion?))
39 The convention is due to LISP, an early but highly advanced programming language designed in 1958. Scheme inherited many ideas from LISP, but it is a different language.