Newsgroups: comp.lang.lisp
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!m.cs.uiuc.edu!ibma0.cs.uiuc.edu!sunc2.cs.uiuc.edu!epstein
From: epstein@sunc2.cs.uiuc.edu (Milt Epstein)
Subject: Re: Tradition Lisp code formatting
Sender: news@ibma0.cs.uiuc.edu
Message-ID: <2864C3CE.46E7@ibma0.cs.uiuc.edu>
Date: Sun, 23 Jun 1991 15:52:45 GMT
References: <20899@sdcc6.ucsd.edu>
Organization: University of Illinois at Urbana-Champaign
Lines: 131

In <20899@sdcc6.ucsd.edu> sboswell@sdcc13.ucsd.edu (....What Is?....) writes:

>I wanted to post this a long time ago but feared starting a flame war.
>But my curiosity has finally gotten the better of me.  I must know. :)
>
>How did the traditional style of Lisp code turn out to be so crunched
>together?

Well, I guess I consider myself a LISP programmer (common lisp) --
it's been the language I've used most the last few years, although I
have written some C stuff, and before that PASCAL -- so I'll offer
some comments -- although I don't have any amazing insights.


>In languages like C, the trend has been to space everything out so
>that blocks are visible (see GNU Emacs "c-mode" to see what I mean,
>if you don't.)  I find it much more readable like that.  But in my
>Lisp books, it seems, comparatively, smashed together!  Here's an
>example, from page 115 of _Lisp: 3rd Edition_ by Patrick Henry
>Winston and Berthold Klaus Paul Horn:
>
>(defun count-outlyers (list-of-elements)
>  (let ((result 0))
>    (dolist (element list-of-elements
>		     result)
>    (when (or (> elements boiling)
>	      (< element freezing))
>      (setf result (+ result 1))))))

For what it's worth, I would've done this function this way (assuming
it was common lisp):

(defun count-outlyers (list-of-elements &aux (result 0))
  (dolist (element list-of-elements result)
    (when (or (> elements *boiling*)
	      (< element *freezing*))
      (incf result))))

(BOILING and FREEEZING are global variables, I assume.)


>I would have formatted it this way:
>
>(defun count-outlyers (list-of-elements)
>    (let
>	(
>	    (result 0)
>	)
>	(dolist
>	    (element list-of-elements result)
>	    (when
>		(or
>		    (> element boiling)
>		    (< element freezing)
>		)
>	        (setf result (+ result 1))
>	    )
>	)
>    )
>)

Well, as you might expect, I find your first version (and my version
too, of course) much more readable and comprehendable than this second
one.  This second one seems much too spread out and has wasted space
-- when I say that, I mean space that doesn't necessarily help make
the code more readable.  I tried to think about why this might be so,
and came up with the following.

OK, what's the major difference between a language like LISP and a
language like C.  Well, LISP is functional programming and C is
imperative.  What are the consequences of this?  I think that the
goals of formatting are the same in each case (to make things more
readable), but they are realized differently due to the different
styles of the languages.

For one thing, what constitutes "blocks" of code differs.  In LISP,
the blocks will typically be indicated by separate functions, so they
are inherently distinct (and you'll have white space inbetween them).
In C, you may have distinct blocks within the same function (confusing
-- different use of the same term), so you may need to put white space
in to separate the blocks.

Another thing is that the relationship between one line of code and
the next differs.  In LISP, since everything is function calls, the
next line will probably be the arguments to a function call, so you'd
like to have them relatively close by to see what is going on.  In my
personal style (I'm not sure what other LISPers do), I tend to write
small functions, so they may often be only one function call (like a
let, dolist, cond, if), and it often turns out that everything is done
via nested function calls -- and then it seems like spreading things
out makes it harder to see what is going on.  This is the case in the
sample function you gave (and maybe that is why I don't like your
second version).  So, really, this function is just one line of code.
In C, different lines are usually distinct steps or commands, so they
don't need to be so close together.

I'll add that when I do occasionally write a program in C or PASCAL,
I do use this spread out style more, although I still tend to write
small functions.


>So far, I've only found one other person who formats the way I do,
>and he hates Lisp nowadays :-( so although it's not a very scientific
>conclusion, I'd say there's at least a chance of programmers being
>turned off by Lisp because they feel lost in all the parentheses and
>cannot immediately divine the structure.  (He would get his Lisp
>assignments back from the TA, re-formatted to the traditional way :)

I think any different language takes a little getting used to -- if
you just bear with it a little while and get more experience with it,
things will become easier.  Actually, I've TA'd a class that uses LISP
several times, and I've noticed a fair number of people that come from
a C-like background -- not just in the way they format, but in the way
they write the functions.  I've seen many a function formatted like
your second version above (and although I don't like it, I neither
re-format it nor deduct for it, although I do point out the preferred
style, which doesn't always make a difference :-).


>Please give me your thoughts on this.  No Holy War(TM) intended. :-|

What?!?!  You think you can start comparing C and LISP and not start a
holy war?!?!

:-)

-- 
Milt Epstein
Department of Computer Science
University of Illinois
epstein@cs.uiuc.edu
