Book review: "Lisp Style and Design" 
Author Message
 Book review: "Lisp Style and Design"

Quote:

>g. A Lisp style book espousing readability should imitate Winston and
>   encourage use of "first" and "rest" when discussing lists, and leave
>   mention of "car" and "cadr" for the folklore section. The authors present
>   the latter operators first. (p32,42)

FIRST and REST are right for some cases, wrong for others.

And what's so bad about car and cdr anyway?



Fri, 14 Oct 1994 04:26:22 GMT  
 Book review: "Lisp Style and Design"

Quote:

>g. A Lisp style book espousing readability should imitate Winston and
>   encourage use of "first" and "rest" when discussing lists, and leave
>   mention of "car" and "cadr" for the folklore section. The authors present
>   the latter operators first. (p32,42)
Jeff Dalton writes:
>FIRST and REST are right for some cases, wrong for others.
>And what's so bad about car and cdr anyway?

In "Lisp" 3rd Ed. page 21, Winston states
  "FIRST and REST were originally called CAR and CDR because of the way
   they were implemented on the ancient IBM 704 computer."

On page 104, Winston states:
  "Mapcar is perhaps the most unfortunately-named primitive in Lisp.
   The map part is alright ... The car part, however, comes from the
   now-obsolete CAR primitive ... MAP-ELEMENTS would have been a better name."

In "AI Programming" page 14, Norvig states:
  "I'm sure you'll agree that first and rest are much better names, and they
   will be used whenever we are talking about lists. However, we will continue
   to use car and cdr on occasion when we are considering a pair of values
   that are not considered as a list."

I think that, aside from the uses Norvig mentions, car and cdr are "bad"
because their names are obscure and therefore they diminish sw readability.
Good software should be written with its future readers in mind.

This was an annoying, but not very important, aspect of a useful book.
While we're at it, I wish the comp.lang.lisp FAQ style recommendations
would at least mention this.

Marc Riese
Swiss Federal Institute of Technology
Lausanne



Sat, 15 Oct 1994 00:00:34 GMT  
 Book review: "Lisp Style and Design"

Quote:


>>g. A Lisp style book espousing readability should imitate Winston and
>>   encourage use of "first" and "rest" when discussing lists, and leave
>>   mention of "car" and "cadr" for the folklore section. The authors present
>>   the latter operators first. (p32,42)

>Jeff Dalton writes:
>>FIRST and REST are right for some cases, wrong for others.
>>And what's so bad about car and cdr anyway?
>In "Lisp" 3rd Ed. page 21, Winston states
>  "FIRST and REST were originally called CAR and CDR because of the way
>   they were implemented on the ancient IBM 704 computer."

Their etymology is not really significant.  Many Lisp experts consider it a
Good Thing that CAR and CDR are essentially meaningless.  There's no
real-world metaphor for them; a cons is like a box with two equivalent but
distinct compartments.  They could be called CONS-LEFT-PART and
CONS-RIGHT-PART, but there's nothing really left/right about them except
that this is the way they're often represented on 2-d paper, screens, or
blackboards (but I wouldn't be surprised if they were represented
"backwards" in Hebrew or Arabic speaking areas); in the box analogy, a box
can be rotated, but its compartments retain their identity.  They could be
called CONS-PART1 and CONS-PART2, but this implies an ordering to a cons
that doesn't exist (except that this is the order of the arguments to the
CONS function -- but if keyword arguments had existed in the 60's then
perhaps it could have taken :CAR and :CDR keywords so that the ordering
wouldn't be necessary).  Perhaps if the nonsense words "foo" and "bar" had
been in use in the early 60's they might have been called CONS-FOO and
CONS-BAR.

Quote:
>On page 104, Winston states:
>  "Mapcar is perhaps the most unfortunately-named primitive in Lisp.
>   The map part is alright ... The car part, however, comes from the
>   now-obsolete CAR primitive ... MAP-ELEMENTS would have been a better name."

Well, the mapping functions are full of poor names.  How is one to remember
which of MAPC/MAPCAR and MAPL/MAPLIST return the results (my mnemonic is
that the ones with long names build results)?  MAPCAN and MAPCON are like
MAPCAR and MAPLIST except that they NCONC the results rather than listing
them, but how can you tell which maps to which?  Had the Common Lisp
designers wished to tackle this, I suspect we'd have gotten a generic
MAP-LIST function with KEY and RESULT-BUILDER arguments.  If we just wanted
better names for the existing functions, we'd have something like
MAP-ELEMENTS, MAP-TAILS, MAP-ELEMENTS-LIST-RESULTS, MAP-TAILS-LIST-RESULTS,
and MAP-ELEMENTS-NCONC-RESULT, and MAP-TAILS-NCONC-RESULTS.

Quote:
>In "AI Programming" page 14, Norvig states:
>  "I'm sure you'll agree that first and rest are much better names, and they
>   will be used whenever we are talking about lists. However, we will continue
>   to use car and cdr on occasion when we are considering a pair of values
>   that are not considered as a list."

>I think that, aside from the uses Norvig mentions, car and cdr are "bad"
>because their names are obscure and therefore they diminish sw readability.
>Good software should be written with its future readers in mind.

I think this is somewhat a religious matter.  I think any respectable Lisp
programmer should be expected to understand the relationship between conses
and lists; this is too fundamental an aspect of Lisp to be completely
abstracted away.  Therefore, there should be nothing confusing about the
use of CDR on lists.

CAR and CDR are part of the normal Lisp vocabulary.  We have phrases like
"cdr'ing down a list" (which was probably more widely appreciated in the
days before DOLIST and LOOP, when you actually had to write the calls to
CDR in your DO loops).  Even if you don't personally like them, they're
common enough idioms that you can't simple relegate them to a footnote or
appendix on archaic style.  Idioms are like that; taken out of context,
they are generally horrible style, but once you realize that they're so
commonly used that everyone just recognizes them as a unit then they don't
matter.

Maybe I'm just stuck in my ways.  When I learned Lisp (about 12 years ago),
FIRST and REST weren't even mentioned.  I don't think they were in the
MacLisp environment by default, but many people defined them as macros that
expanded into CAR and CDR.  I never got into the habit of using FIRST and
REST, but still consider my code good style.
--
Barry Margolin
System Manager, Thinking Machines Corp.




Sat, 15 Oct 1994 04:41:27 GMT  
 Book review: "Lisp Style and Design"

   I think that, aside from the uses Norvig mentions, car and cdr are "bad"
   because their names are obscure and therefore they diminish sw readability.
   Good software should be written with its future readers in mind.

While I agree that using FIRST/REST for list accessors and CAR/CDR for
pair accessors only -- an idea that predates including FIRST and REST in
the language definition, by the way (see, e.g., Allen's _Anatomy of
LISP_) -- makes a lot of sense, anyone who finds that "old-fashioned"
uses of CAR and CDR significantly diminishes readability has no business
reading Lisp!

                                                        -- rar



Sat, 15 Oct 1994 07:34:06 GMT  
 Book review: "Lisp Style and Design"
Quote:
Barry Margolin writes:
> Many Lisp experts consider it a Good Thing that CAR and CDR are
> essentially meaningless.  There's no real-world metaphor for them;

[interesting stuff about alternative names]

Quote:
> the mapping functions are full of poor names.

[more interesting stuff about mapping names]

Quote:
> I think any respectable Lisp programmer should be expected to understand
> the relationship between conses and lists; this is too fundamental an
> aspect of Lisp to be completely abstracted away.

All the points above are well taken. Like I said in my original posting,
I am certainly not a Lisp expert. I'm learning.

Quote:
> they're common enough idioms that you can't simple relegate them to
> a footnote or appendix on archaic style.

Perhaps that's what mislead me in the first place, because Winston
does just that! Anyway, thanks for the information.

Quote:
Bob Riemenschneider writes:
>anyone who finds that "old-fashioned"
>uses of CAR and CDR significantly diminishes readability has no business
>reading Lisp!

Winston states that they are "obsolete" and "ancient".
Norvig says that they were based on the original implementation, and then
writes "I'm sure you'll agree that FIRST and REST are much better names".
Obviously, readibility is a significant criterion for them here.

Marc Riese
Swiss Federal Institute of Technology
Lausanne



Sat, 15 Oct 1994 16:57:22 GMT  
 Book review: "Lisp Style and Design"

Quote:

>g. A Lisp style book espousing readability should imitate Winston and
>   encourage use of "first" and "rest" when discussing lists, and leave
>   mention of "car" and "cadr" for the folklore section. The authors present
>   the latter operators first. (p32,42)
[...]
>In "AI Programming" page 14, Norvig states:
>  "I'm sure you'll agree that first and rest are much better names, and they
>   will be used whenever we are talking about lists. However, we will continue
>   to use car and cdr on occasion when we are considering a pair of values
>   that are not considered as a list."


Quote:
>I think this is somewhat a religious matter.  I think any respectable Lisp
>programmer should be expected to understand the relationship between conses
>and lists; this is too fundamental an aspect of Lisp to be completely
>abstracted away.  Therefore, there should be nothing confusing about the
>use of CDR on lists.

Well, I agree with Barry that it is somewhat of a religious matter, and
that for the serious LISP programmer it would not be confusing. However,
I have two small reasons why I tend to prefer first/rest on lists.

(A) It reminds me (and the reader) what I'm doing. Ie if they see car/cdr
that would indicate that conses are being used for something besides lists.
I think this is more or less what Peter Norvig was getting at above.

(B) There is, IMHO, more of a role for abstracting lists for beginners than
for experts. I teach AI and AI programming to part-time MS students here at
Johns Hopkins, and think it is preferable to introduce lists as an abstract
entity first, and only talk about how it is actually implemented somewhat
later. In fact, I sheepishly admit that, early on, most of my students
don't know that car/cdr are two "equal" slots, that the second argument
to cons doesn't have to be a list, etc. Basically, they don't even know
what conses *are* for quite a while! Now, these are AI and AI Programming
courses, not LISP courses, so LISP is mostly just a tool to illustrate
the AI techniques (especially in the first course). But nevertheless, I
think there *is* some benefit to abstracting lists in this non-LISP-expert
crowd, at least at the beginning.

                                        - Marty
------------------------------------------------------

Artificial Intelligence Lab, AAI Corp, PO Box 126, Hunt Valley, MD 21030

(setf (need-p 'disclaimer) NIL)



Sat, 15 Oct 1994 21:41:25 GMT  
 Book review: "Lisp Style and Design"

Quote:
>>On page 104, Winston states:
>>  "Mapcar is perhaps the most unfortunately-named primitive in Lisp.
>>   The map part is alright ... The car part, however, comes from the
>>   now-obsolete CAR primitive ... MAP-ELEMENTS would have been a better name."
>Well, the mapping functions are full of poor names.  

Amen.  I deem it unacceptable to use any mapping functions whatsoever.  Ditto
for all _do_ forms.  They are tough to write and impossible to read.  There's
no excuse for not using a loop macro, which is instantly readable by anyone.

--Hans



Sun, 16 Oct 1994 04:53:54 GMT  
 Book review: "Lisp Style and Design"

    Date: Tue, 28 Apr 1992 16:53 EDT


    >>On page 104, Winston states:
    >>  "Mapcar is perhaps the most unfortunately-named primitive in Lisp.
    >>   The map part is alright ... The car part, however, comes from the
    >>   now-obsolete CAR primitive ... MAP-ELEMENTS would have been a better name."
    >Well, the mapping functions are full of poor names.  

    Amen.  I deem it unacceptable to use any mapping functions whatsoever.  Ditto
    for all _do_ forms.  They are tough to write and impossible to read.  There's
    no excuse for not using a loop macro, which is instantly readable by anyone.

This is a joke, right?  I have seen uses of LOOP, some of them
written by me in an earlier life, that can only be described as
abominations.  I use DOLIST, DOTIMES, and MAP frequently and would
hardly call them unreadable.

And hasn't this whole discussion has become pointless anyway?  We
all know that bad programs can be written in any language, as well
as good programs.  It's a matter of discipline on the part of the
programmer, not on piddly things like whether you use FIRST instead
of CAR, REST instead of CDR, or LOOP instead of DOLIST.



Sun, 16 Oct 1994 07:17:03 GMT  
 Book review: "Lisp Style and Design"
|>
|> Amen.  I deem it unacceptable to use any mapping functions whatsoever.  Ditto
|> for all _do_ forms.  They are tough to write and impossible to read.  There's
|> no excuse for not using a loop macro, which is instantly readable by anyone.
|>
|> --Hans

WRONG!  loop is one of the major abominations in common lisp, what with all
of its reserved words.  how are the following "instantly readable"?  it is not
instantly apparent what the semantics of these are, let alone how one should
use them.  talk about impossible to read!  this is what happens when one gets
the use of special forms and macros.  you have to KNOW what the syntax and
semantics of these forms are in order to use/read them.  the map FUNCTIONS
don't suffer from this affliction -- they're functions like (most of) everything
else in lisp.  of course, the semantics are important as are the order of
arguments.  if this is considered a problem, then one probably shouldn't be
using lisp at all as this "problem" applies to all functions in lisp.

although i prefer to use recursion in most instances, i find do useful as it is
the closest of these forms to recursion.

here are a few of the more arcane loop clause reserved words.  there are even
restrictions on where/when some of these can be used.  ugh!

thereis
minimizing
always
maximize
summing
nconcing

david

as a colleague recently remarked:  "to iterate is human; to recurse, divine."



Sun, 16 Oct 1994 07:20:49 GMT  
 Book review: "Lisp Style and Design"

Quote:

>Amen.  I deem it unacceptable to use any mapping functions whatsoever.  Ditto
>for all _do_ forms.  They are tough to write and impossible to read.  There's
>no excuse for not using a loop macro, which is instantly readable by anyone.

I think they all have their appropriate uses.

The mapping functions are useful when all you want to do is apply an
existing function to every element of a list.

(mapcar #'cons list1 list2)

(mapc #'print objects)

are quite simple to write *and read*.

I don't find too much use for the original DO these days, but DOLIST and
DOTIMES are perfectly fine.  DOLIST is nice for things that would have
required a lambda expression when using MAPC.  For instance, I find

(dolist (item list)
  (print (car item)))

easier to read and write than

(mapc #'(lambda (item) (print (car item))) list)

Finally, I use LOOP when I'm doing something that can make use of its
automatic result mechanisms (usually COLLECTING or SUMMING) or I'm using a
combination of multiple simultaneous iteration paths.  I prefer

(loop for i upfrom 0
      for item in list
  ...)

to

(do ((i 0 (1+ i))
     (tail list (cdr tail))
     item)
    ((null tail) ...)
  (setq item (car tail))
  ...)

When generators and gatherers become more widely implemented I think they
will usually be useful where LOOP currently is.

Quote:

>WRONG!  loop is one of the major abominations in common lisp, what with all
>of its reserved words.

Well, I generally find LOOP pretty readable, but I admit that LOOP has many
details that can be used to make it as incomprehensible as anything else
(this is a corollary to the statement that it's possible to write poor
programs in any language).  The AND connective between iteration clauses is
relatively uncommon.  The mechanism for multiple collectors is a bit
tricky.  Whether certain exit mechanisms execute the FINALLY clause can be
confusing.  And I usually have to look up what the return value of a loop
using the THEREIS or ALWAYS collector is (however, I don't understand why
Mr. Schulenburg has trouble understanding the MAXIMIZING or SUMMING
collectors).

Note, however, that the keywords in LOOP aren't really "reserved".  They
can be used as variable names, since it's always possible to distinguish
variables from keywords by context.  The following is valid and unambiguous
(but that doesn't make it good style):

(deftype of-type ...)
(defvar = ...)
(defvar in ...)
(defvar from ...)
(defvar to ...)
(defvar by #'...)
(defvar collecting ...)

(loop with with of-type of-type = =
      for for in in
      and and from from to to by by
      collecting collecting)
--
Barry Margolin
System Manager, Thinking Machines Corp.




Sun, 16 Oct 1994 08:31:02 GMT  
 
 [ 81 post ]  Go to page: [1] [2] [3] [4] [5] [6]

 Relevant Pages 

1. Book review: "Lisp Style and Design"

2. Book request - "Smalltalk with Style"

3. "HDL Chip Design" book

4. "ANSI Common Lisp" an excellent book

5. "On Lisp" book

6. Book query: Miller/Benson,Lisp style and Design

7. "Into the Realm of Oberon", a review

8. Linux Journal reviews "Learning Python"

9. Review of "Migrating to Fortran 90"

10. Review of "Migrating to Fortran 90", J.F. Kerrigan

11. Review of "The Craft of Prolog"

12. string.join(["Tk 4.2p2", "Python 1.4", "Win32", "free"], "for")

 

 
Powered by phpBB® Forum Software