home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!uknet!edcastle!aiai!jeff
- From: jeff@aiai.ed.ac.uk (Jeff Dalton)
- Newsgroups: comp.lang.lisp
- Subject: Re: style-guide
- Message-ID: <7376@skye.ed.ac.uk>
- Date: 27 Aug 92 18:11:28 GMT
- References: <HALTRAET.92Aug13043710@monsun.si.no>
- Sender: news@aiai.ed.ac.uk
- Organization: AIAI, University of Edinburgh, Scotland
- Lines: 125
-
- In article <HALTRAET.92Aug13043710@monsun.si.no> haltraet@monsun.si.no (Hallvard Tr{tteberg) writes:
- >I'm writing a style-guide for a big Lisp project, and would like
- >comments on my first draft and suggestion for the empty chapters.
-
- Thanks for posting your style guide. I think most of it is
- excellent, but I disagree with some things.
-
- 1. The general rule "use the most specific construct" is a useful
- guideline, but it's presented as if it should override (almost) every
- other consideration. In addition, I think it's a mistake to expect
- a single best answer in every case, and the rigid application of the
- "most specific" rule looks like it has that end in mind.
-
- The application of this rule that I find least reasonable is the one
- that decides between MAPC and DOLIST. I don't think it's right to say
- to use MAPC instead of DOLIST unless you want to RETURN from the loop.
- There's nothing wrong with using DOLIST w/o RETURN and nothing wrong
- with using MAPC for some reason other than "not using RETURN". Maybe
- you want to bring out a similarity to some other code that uses a
- different mapping function. Or maybe you just happen to prefer
- mapping functions.
-
- It's also possible that using the most specific construct will result
- in code that is cleverer but less clear.
-
- A better rule is this one (also from your guide):
-
- The general rule, when choosing technique, is to use idioms that
- are easy to spot.
-
- (BTW, I see nothing wrong in using SETQ instead of SETF on variables.)
-
- 2. I think that variables introduced by DEFPARAMETER are at least as
- close to DEFVAR variables as they are constants. For one thing,
- treating parameters as constants implies that they should never be
- rebound. But if they can "be changed (possibly at run-time)", it may
- be better to change them by binding rather than assignment. The
- difference between a paramater and a (DEFVAR) variable is, I would
- say, that it's the program that changes the value of a variable and
- the user (or "logical user") who changes the value of a parameter.
- This does not, to my mind, imply that parameters are closer to
- constants than to variables.
-
- 3. I think the problem of spotting dependencies in LET* is often
- overemphasized (though what you say is reasonable). People find
- it fairly easy to understand sequntial actions, and I think it
- often helps to use LET* when what you want to say is "first do
- (or compute) this and remember the result, then do/compute that
- and remember the result, ...". The really confusing case is when
- there's some variable, say X, that's bound in the LET* with another
- instance of X outside the LET* so that references in the init forms
- might refer to either one. So long as refs are always to names bound
- earlier in the LET* or to names that are not bound by the LET* at all,
- there's a very wide range of cases where LET* is not difficult to
- understand.
-
- 4. I don't think CATCH and THROW must be avoided, although these days
- it may be better in many cases to use the condition system instead.
- It's also better to use BLOCK and RETURN-FROM when you don't have to
- contort the code to do so.
-
- 5. Bear in mind that DECLAIMing something INLINE may not result in
- it being inlined. If you really need the extra efficiency you may
- have to use a macro or a compiler macro. (Unless someone posts a
- DEFSUBST (which defines a function and a matching compiler macro)
- that we can all use.)
-
- 6. Note that type declarations _can_ lead to reduced efficiency
- (even when you're optimizing for speed). The reason is that the
- variable in question may be stored in a space-efficient, type-specific
- way so that every time you return (an element of) the value of the
- variable a new object must be created on the heap.
-
- This is not necessarily a reason to avoid declarations, but it is
- something to bear in mind.
-
- However, I think it removes one of the advanatges of Lisp if you
- end up declaring everything, whether for documentation or otherwise.
-
- 7. A lot of your advice on sequences seems to be saying "use
- sequence functions instead of LOOP" (although LOOP is explicitly
- discussed as an alternative in only a few cases). I think that
- much of the time the choice between LOOP and something else is
- largely a matter of taste.
-
- 8. There _are_ cases when it is reasonable to use EVAL.
-
- Note too that it's always possible to avoid EVAL by using the
- following trick:
-
- (defun secretly-eval (form)
- (funcall (coerce `(lambda () ,form) 'function)))
-
- This suggests that you will untimately need some guidelines about
- when it's reasonable to construct code and eveluate it even if you
- rule out the use of EVAL per se.
-
- 9. One area that I think needs some emphasis is indentation.
- Indentation is extremely important in Lisp, more so than in other
- languages, and I see a lot of bizarrely indented code even from
- people who are using a textbook full of good examples they could
- imitate. The aim of indentation should be to make it possible
- for someone reading the code to pay very little attention to
- individual parentheses. All they should have to notice is the
- general shape of the paren groups and how forms line up.
-
- 10. Another issue that needs more attention is that of organizing
- systems that involve many files and more than one package. There's
- been some discussion of this recently in comp.lang.clos. (There's
- a lot of good advice in Sonya Keene's book on CLOS, but one thing
- she doesn't discuss is how to use packages and CLOS together.
- She regards packages as a general Common Lisp issue, but I think
- it's become clear that CLOS raises some new issues regarding
- package use (or else it makes certain "old" issues more significant).)
-
- ---
-
- I think it's important to bear in mind that different audiences
- have different needs. In some contexts, it is right to have some
- rules (such as "never use EVAL") that would be too strong in others.
- That I disagree with some of your advice when it's directed to the
- net in general does not mean I'd say it's wrong for your big Lisp
- project.
-
- -- jd
-