home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / lisp / 2315 < prev    next >
Encoding:
Internet Message Format  |  1992-08-27  |  6.2 KB

  1. Path: sparky!uunet!mcsun!uknet!edcastle!aiai!jeff
  2. From: jeff@aiai.ed.ac.uk (Jeff Dalton)
  3. Newsgroups: comp.lang.lisp
  4. Subject: Re: style-guide
  5. Message-ID: <7376@skye.ed.ac.uk>
  6. Date: 27 Aug 92 18:11:28 GMT
  7. References: <HALTRAET.92Aug13043710@monsun.si.no>
  8. Sender: news@aiai.ed.ac.uk
  9. Organization: AIAI, University of Edinburgh, Scotland
  10. Lines: 125
  11.  
  12. In article <HALTRAET.92Aug13043710@monsun.si.no> haltraet@monsun.si.no (Hallvard Tr{tteberg) writes:
  13. >I'm writing a style-guide for a big Lisp project, and would like
  14. >comments on my first draft and suggestion for the empty chapters.
  15.  
  16. Thanks for posting your style guide.  I think most of it is 
  17. excellent, but I disagree with some things.
  18.  
  19. 1. The general rule "use the most specific construct" is a useful
  20. guideline, but it's presented as if it should override (almost) every
  21. other consideration.  In addition, I think it's a mistake to expect
  22. a single best answer in every case, and the rigid application of the
  23. "most specific" rule looks like it has that end in mind.
  24.  
  25. The application of this rule that I find least reasonable is the one
  26. that decides between MAPC and DOLIST.  I don't think it's right to say
  27. to use MAPC instead of DOLIST unless you want to RETURN from the loop.
  28. There's nothing wrong with using DOLIST w/o RETURN and nothing wrong
  29. with using MAPC for some reason other than "not using RETURN".  Maybe
  30. you want to bring out a similarity to some other code that uses a
  31. different mapping function.  Or maybe you just happen to prefer
  32. mapping functions.
  33.  
  34. It's also possible that using the most specific construct will result
  35. in code that is cleverer but less clear.  
  36.  
  37. A better rule is this one (also from your guide):
  38.  
  39.    The general rule, when choosing technique, is to use idioms that
  40.    are easy to spot.
  41.  
  42. (BTW, I see nothing wrong in using SETQ instead of SETF on variables.)
  43.  
  44. 2. I think that variables introduced by DEFPARAMETER are at least as
  45. close to DEFVAR variables as they are constants.  For one thing,
  46. treating parameters as constants implies that they should never be
  47. rebound.  But if they can "be changed (possibly at run-time)", it may
  48. be better to change them by binding rather than assignment.  The
  49. difference between a paramater and a (DEFVAR) variable is, I would
  50. say, that it's the program that changes the value of a variable and
  51. the user (or "logical user") who changes the value of a parameter.
  52. This does not, to my mind, imply that parameters are closer to
  53. constants than to variables.
  54.  
  55. 3. I think the problem of spotting dependencies in LET* is often
  56. overemphasized (though what you say is reasonable).  People find
  57. it fairly easy to understand sequntial actions, and I think it
  58. often helps to use LET* when what you want to say is "first do
  59. (or compute) this and remember the result, then do/compute that
  60. and remember the result, ...".  The really confusing case is when
  61. there's some variable, say X, that's bound in the LET* with another
  62. instance of X outside the LET* so that references in the init forms
  63. might refer to either one.  So long as refs are always to names bound
  64. earlier in the LET* or to names that are not bound by the LET* at all,
  65. there's a very wide range of cases where LET* is not difficult to
  66. understand.
  67.  
  68. 4. I don't think CATCH and THROW must be avoided, although these days
  69. it may be better in many cases to use the condition system instead.
  70. It's also better to use BLOCK and RETURN-FROM when you don't have to
  71. contort the code to do so.
  72.  
  73. 5. Bear in mind that DECLAIMing something INLINE may not result in
  74. it being inlined.  If you really need the extra efficiency you may
  75. have to use a macro or a compiler macro.  (Unless someone posts a
  76. DEFSUBST (which defines a function and a matching compiler macro)
  77. that we can all use.)
  78.  
  79. 6. Note that type declarations _can_ lead to reduced efficiency
  80. (even when you're optimizing for speed).  The reason is that the
  81. variable in question may be stored in a space-efficient, type-specific
  82. way so that every time you return (an element of) the value of the
  83. variable a new object must be created on the heap.
  84.  
  85. This is not necessarily a reason to avoid declarations, but it is
  86. something to bear in mind.
  87.  
  88. However, I think it removes one of the advanatges of Lisp if you
  89. end up declaring everything, whether for documentation or otherwise.
  90.  
  91. 7. A lot of your advice on sequences seems to be saying "use
  92. sequence functions instead of LOOP" (although LOOP is explicitly
  93. discussed as an alternative in only a few cases).  I think that
  94. much of the time the choice between LOOP and something else is
  95. largely a matter of taste.
  96.  
  97. 8. There _are_ cases when it is reasonable to use EVAL.
  98.  
  99. Note too that it's always possible to avoid EVAL by using the
  100. following trick:
  101.  
  102.   (defun secretly-eval (form)
  103.     (funcall (coerce `(lambda () ,form) 'function)))
  104.  
  105. This suggests that you will untimately need some guidelines about
  106. when it's reasonable to construct code and eveluate it even if you
  107. rule out the use of EVAL per se.
  108.  
  109. 9. One area that I think needs some emphasis is indentation.
  110. Indentation is extremely important in Lisp, more so than in other
  111. languages, and I see a lot of bizarrely indented code even from
  112. people who are using a textbook full of good examples they could
  113. imitate.  The aim of indentation should be to make it possible
  114. for someone reading the code to pay very little attention to
  115. individual parentheses.  All they should have to notice is the
  116. general shape of the paren groups and how forms line up.
  117.  
  118. 10. Another issue that needs more attention is that of organizing
  119. systems that involve many files and more than one package.  There's
  120. been some discussion of this recently in comp.lang.clos.  (There's
  121. a lot of good advice in Sonya Keene's book on CLOS, but one thing
  122. she doesn't discuss is how to use packages and CLOS together.
  123. She regards packages as a general Common Lisp issue, but I think
  124. it's become clear that CLOS raises some new issues regarding
  125. package use (or else it makes certain "old" issues more significant).)
  126.  
  127. ---
  128.  
  129. I think it's important to bear in mind that different audiences
  130. have different needs.   In some contexts, it is right to have some
  131. rules (such as "never use EVAL") that would be too strong in others.
  132. That I disagree with some of your advice when it's directed to the
  133. net in general does not mean I'd say it's wrong for your big Lisp
  134. project.
  135.  
  136. -- jd
  137.