Course Grades Email
Welcome
Policies Grades Inc Intgrty Preface Part I Chap 1 Chap 2 Chap 3 XEmacs Chap 4 Chap 5 Chap 6 Chap 7 Chap 8 Chap 9 Part II Chap 10 Chap 11 Chap 12 Chap 13 Chap 14 Chap 15 Chap 16 Chap 17 Chap 18 Chap 19 Chap 20 Chap 21 Chap 22 Chap 23 Part III Chap 24 Chap 25 Chap 26 Chap 27 Chap 28 Chap 29 Chap 30 Chap 31 Chap 32 | CHAPTER 17: RECURSION ON LISTS, PART 2---SYNTHESIS - Corrections
-
- page 121, line -13: Change
((+ 3 5) - 6 * 8)) to ((+ 3 5) - 6 * 8) - page 121, line -7: Change combine-expression to enclose-expression
- Page 297, lines 1 - 11: Change
17.34 (defun enclose-expression (expr) "EXPR is a list representing an arithmetic expression (using only the operators + and -) in normal infix notation. Returns a list whose one member is EXPR transformed into Cambridge Prefix Notation." (check-type expr list) (cond ((< (length expr) 3) expr) (t (combine-expr (second expr) (first expr) (enclose-expression (nthcdr 2 expr)))))) to 17.34 (defun enclose-expression (expr) "EXPR is a list representing an arithmetic expression (using only the operators + and -) in normal infix notation. Returns a list whose one member is EXPR transformed into Cambridge Prefix Notation." (check-type expr list) (cond ((< (length expr) 3) expr) (t (enclose-expression (combine-expr (second expr) (first expr) (nthcdr 2 expr)))))) - Notes
-
- Read Chapter 17. This chapter is the heart of the book and the course. When you have succeeded in doing the exercises through Chapter 17, you will have earned a grade of C.
- Exercises 17.1 through 17.8 are concerned with the identity of lists as objects. They use the function
eql as the basic test of identity. Two Lisp forms form1 and form2 may evaluate to the identical Lisp object, in which case, (eql form1 form2) will evaluate to True. If they don't evaluate to the identically same object, (eql form1 form2) will evaluate to False (that is, NIL ). It may be that form1 and form2 evaluate to lists that have the same members in the same order, and yet are not identical, in which case (eql form1 form2) will evaluate to False, even though (equal form1 form2) will evaluate to True, because equal is more concerned with appearing the same than actually being identical. One reason this is important is that lists can have lists as members. If two members of a list are eql , that object is stored only once, but if two members of a list are only equal lists, twice as much storage is used. Another reason this is important is that many Lisp functions use eql as the default equality tester, and you might be surprised at the behavior of these functions if you didn't realize the difference between eql objects and equal objects. These exercises also illustrate the fact that, given a list, some functions return a list that is eql to the argument list, or eql to some sublist of it, while other functions copy all or part of their argument lists. In particular, append takes two lists, l1 and l2 , and returns one list that includes a copy of l1 , but incorporates l2 in it uncopied. That is, some sublist of (append l1 l2) is eql to l2 , but no sublist of (append l1 l2) is eql to l1 . What you might do even before doing 17.1 is compare Lisp's value of (eql '(a b c) '(a b c)) to its value of (equal '(a b c) '(a b c)) You'll need a list copying function for Exercise 17.2. Either create one by doing Exercise 17.1, or just use copy-list Either use the * technique as specified in these exercises, or define functions to use. For example, you could do 17.2 by doing CH17(84): (defun eql-copy (lst) "Returns T if a list is eql to a copy of itself; NIL otherwise." (eql lst (copy-list lst))) EQL-COPY CH17(85): (eql-copy '(a b c)) - Notice that there two ways of shadowing a symbol. If you have already defined a package, and are interacting with the Lisp listener in that package, and you want to shadow a symbol, just evaluate
(shadow 'symbol) . For example, USER(82): (defpackage ch17) #<The CH17 package> USER(83): ... USER(99): (shadow 'identity) But, if you are defining a package and know symbols you want to shadow, or if you have a defpackage form in a file, you should use the :shadow subform within the defpackage form, such as, USER(82): (defpackage ch17 (:shadow copy-list identity)) #<The CH17 package> - 17.9: My version of
reverse1 in the book uses reverse2 as a help function to do all the work. As I say on page 111, "reverse1 does nothing on its own. It just initializes reverse2 's second argument to be () ." An alternative technique is to combine the two functions into one with an optional argument: (defun reverse1 (list1 &optional (list2 '())) "Returns a list consisting of the members of LIST1 in reverse order followed by the members of LIST2 in original order. If LIST2 is omitted, returns a copy of LIST1 with the order of members reversed." (check-type list1 list) (check-type list2 list) (if (null list1) list2 (reverse1 (rest list1) (cons (first list1) list2)))) Here, if reverse1 is called with two arguments, list1 is bound to the first argument and list2 is bound to the second argument. However if reverse1 is called with only one argument, list1 is bound to that argument and list2 is bound to '() . You should do Exercise 17.9 if you need concrete evidence that the reverse defined in the book is a lot slower than reverse1 , in which case you may either use the reverse1 /reverse2 pair, or the reverse1 given above with the optional argument. - Do Exercises 17.9 and 17.10 if you feel they will help your understanding. Common Lisp already has the function
substitute , which acts like subst* . - You needn't do Exercises 17.13 - 17.28.
- Do Exercises 17.29 - 17.32, noting the following:
Submit your updated match.cl file. Please remember to revise the line "This file satisfies the exercises through Exercise ???"
|