From: riese@litsuns1.epfl.ch (Marc Riese)
Newsgroups: comp.lang.lisp
Subject: Book review: "Lisp Style and Design"
Date: 1 Apr 92 08:58:44 GMT


One of the FAQ's on this group is something like "Does anyone know
any good books about how to program well in Lisp?". The most common
response is a pointer to Miller and Benson's "Lisp Style and Design".

I have read it recently and wrote a small review for my own notes,
consisting of a summary, some comments, and some less significant details.
I am posting it in case anyone is interested. Personally, I found
that the book is good, but has significant problems.
My opinion is that of a software engineer. Although I have basic knowledge
of Lisp and CLOS, I am certainly not a Lisp expert.

Perhaps someone could tell us if other such books exist,
if the authors are planning a revised edition, and
if other reviews have been done on this book and where they can be found.

Marc Riese
Swiss Federal Institute of Technology
Lausanne

---------------------------------------------------------------


Title:           Lisp Style & Design
Authors:         Molly M. Miller and Eric Benson
Keywords:        programming book
Source:          Digital Press; 1990; ISBN 1-55558-044-0
X-Refs:          keene88

Summary
-------
a. Book about how to program well in Lisp. Miller wrote the text; Benson coded.
   The authors state that the book is not a Lisp primer and that it
   should benefit those with a basic knowledge of Lisp. However, readers with
   no background in software engineering are advised to supplement this
   Lisp-specific book with any text explaining and justifying the necessity
   of good programming style in general, and the place of good programming
   style in the context of good software engineering over the entire
   software lifecyle.

b. Good programming style aids readability, maintenance and debugging p1.
   Good style comprises efficient algorithms, good organisation, appropriate
   abstractions, well-constructed function definitions, useful commentary, and
   effective degugging p5. Good style must involve all of the following:
   good organisation; good function definitions; adequate algorithms p6.

c. The Preface claims that the authors show "how to design, write, document,
   and debug well-organized programs that use the complete expressive power
   of Lisp effectively." Use of the word "complete" was optimistic for this
   200-odd page book.

d. "You should never have to sacrifice clarity for the sake of efficiency".p138

e. Scattered references to unnecessary but useful compiler optimization 
   possibilities: defining slot types in advance; defining array entry
   types in advance; using vectors and hashtables instead of lists. These
   are completed in Chapter 7.

f. Chapter 3 discusses data structures, operator constructs, and idioms. Much
   good advice is given, although the organisation of details is not clear
   and (fortunately?) it is not complete. Some of the chapter only consists of
   listing the names of a subset of Lisp features. For example, all we learn
   about bit vectors is a collection of key words associated with them.

g. Index is good. Expression is usually clear and shows realism, for example:
  "What seems like a reasonable approach while you are mulling over the
   problem in the shower often looks less robust when you are staring at
   the debugger prompt." p20 The vocabulary is unclear at times. For example,
   one sentence starts as follows: "Similarly, the connotation associated 
   with a construct can become polluted if ..." p31. 
   Exercises are limited to one page as the last appendix.

Comments
--------
a. Good programming style for the authors is limited to 
   aiding readability, maintenance, and debugging - a very short list. 
   (cf Preface & Intro) Good style should give significant priority to 
   reusability, extensibility, and portability. Reusibility is only alluded to
   as "sharing common properties and behavior" p87 and "generalizing" p148. 
   Extensibility is first referred to on page 22 as an attribute of CLOS, and 
   this in a subsection about data structures. Portability is only mentioned 
   as an attribute of Common Lisp. I was very surprised to see that the major
   example of this text depends on a particular compiler! (Lucid)
   If experts cannot write portable code in Lisp, who can?

b. I found the many references to the authors' company, Lucid Inc., to be of
   annoying. Some are simply not necessary.

c. I have seen that the example program was also very complex for students
   having basic knowledge of Lisp. If an exemplary user interface requires 
   such complexity, imagine what non-exemplary work will produce! The example
   does not clearly show how the input data file is created.

d. Bibliography is extremely short granted the wealth of literature on
   programming style. This meagre reading shows itself in the text.
   The book discusses programming style; since this topic is a partial 
   introduction to good software engineering in general, the book should
   show the place of the programming activity in the  context of the 
   software life cycle, but it does not. Chapter 2 informally mixes the
   identification of problem requirements (analysis) with defining a solution
   (design); not good for an introduction and a book that emphasizes
   organisation. It suddenly discusses the design process without having 
   defined the term. It refers to iterative design without reference to
   iterative s/w life cycles, such as the spiral method. Similarly, the
   expression "programmatic interface" is used before it is defined. Such 
   informality is of questionable acceptability for a book about good style. 
   It seems to me that good style requires discipline (hence structure, 
   organisation, and at least some sort of formality) in order to achieve
   its goals.

e. When justifying the use of CLOS, the authors discuss
   inheritance and extensibility. However, "In addition to these legitimate
   concerns, we simply want to try out this new capability of Common Lisp."p22
   Here we have a book about good style stating that one reason why the
   authors are using a certain programming technique is because they
   "want to try [it] out". Considering how many software projects fail because
   of unnecessary complexity, this sentence should not appear in a book
   about style. On a related note, the authors rightly point out that 
   programmers should be careful to maximise (optimise?) their use of the 
   existing features of Lisp.

f. Although tail recursive functions are defined and used, the importance of
   this technique over less efficient recursive functions is not mentioned.
   This is an important point that is not always obvious to those with
   only basic knowledge of Lisp. Similarly, the authors do not clearly show
   when to use mixin classes as opposed to non-mixin classes. p69

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)

h. Needs a more in-depth treatment of good CLOS programming style.

i. Despite the above criticisms, the book contains much good advice.

Details
-------
a. If you want a non-nil value to be returned, use "and" instead of "if".
   When the value returned is not important, use "when" and "unless", which
   are intended to produce side effects, instead of "if". p39.

b. Whenever possible, use defvar and defparameter for special or global
   variables. The documentation function indicates that such variables
   are indeed variables, as opposed to those set by setq. p43-45 
   However, let and let* are preferred for temporary or local variables.p43 

c. defvar does not change global variables already having a value.
   Beware of this when assuming newly loaded code resets old values!

d. Use setf instead of wasting space and cluttering legibility with
   home-made access and update operators. p43

e. mapcar syntax can be more clear than other recursive or iterative 
   constructs.

f. If a function is only called by one other, the authors advise nesting 
   the former in the later using flet or labels p51. I think this can make
   for functions too large to be readable.

g. Although the same name may be used for different entities having different
   scope, the authors correctly point out that whoever maintains the code
   may not realise this. p54

h. Use recursion for hierarchical data structures and iteration for lists.

i. Objects that are difficult to create and allocate at run time, like bitmaps,
   can be kept in a pre-allocated resource pool. p63

j. Good advice on how to avoid problems when writing macros. p83

k. Global variables should be enclosed by asterisks. Predicate names should
   end with "p". p101

l. p102 The first line of a file starting 
   ";;; -*- Mode: Lisp; Syntax: Common-Lisp; Package: PLAN; Base: 10 -*-"
   is called the file options which is parsed by Emacs and Lisp editors to
   determine the editor mode, file buffer syntax, Lisp package of the buffer
   and the numeric base used in the file.
   ;;;; Four semicolons defines file subheadings, like collections of
                         definitions.
   ;;;  Three semicolons are used to document the following function, macro,
                         or variable.
   ;;   Two semicolons are used to describe the following expression
   ;    One semicolon is used for in-line comments

m. An example of dividing code into files (and loading) is given on p107.
   Packages are mainly useful for avoiding symbol name clashes. p110
   Use of declaration files, for extremely large code, ensures proper
   compilation and loading of program constructs. p112

n. For debugging, use: describe, inspect, apropos, apropos-list, trace,
   and step. Common lisp provides constructs for detecting errors and
   going directly to the debugger with them: break, warn, error, cerror,
   assert, check-type, etypecase, ecase, ctypecase, and ccase.

o. For efficiency make use of: "time" and "room"; declarations (type,
   optimise); and compiling.
Newsgroups: comp.lang.lisp