Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news4.ner.bbnplanet.net!news3.near.net!news2.near.net!howland.reston.ans.net!tank.news.pipex.net!pipex!dish.news.pipex.net!pipex!dircon!rheged!simon
From: simon@rheged.dircon.co.uk (Simon Brooke)
Subject: Re: LisP aesthetics (was Re: Testing for EOF)
Message-ID: <DCG7Fp.Hy0@rheged.dircon.co.uk>
Organization: none. Disorganization: total.
References: <3u1f98$l9n@usenet.srv.cis.pitt.edu> <CGAY.95Jul15101459@ix.cs.uoregon.edu> <DC576r.Byw@rheged.dircon.co.uk> <ANDERSON.95Jul25175039@earhart.cs.umass.edu>
Date: Fri, 28 Jul 1995 22:50:12 GMT
Lines: 134

To reiterate: this is about matters of taste and philosophy. If you
disagree, fine. I'm writing about what *I* find elegant and
understandable, not offering the law and the prophets.

Several people have sent me privately improvements on my suggested
function; thanks to all. Interestingly, one of the cleanest was posted
with a throw-away line:

> From: stamant@lindy.cs.umass.edu (Robert St. Amant)
> Why go halfway?  How about the function below:

> (defun char-count (file)
>   (with-open-file (stream file)
>     ;; New and improved, with 100% more recursion
>     ;; and no ugly iteration
>     (labels ((process-line (&optional line (count 0))
>                (if (eq line :eof)
> 		   count
> 		   (process-line (read-line stream nil :eof)
> 				 (+ count (length line) 1)))))
>       (process-line))))

> I wrote the above with tongue in cheek; I actually think it's pretty
> awful.  While Simon writes that LisP doesn't pretend to be like a
> human language, people do have to read it, and I think the original
> code, with the loop, is a lot clearer.

This guy baffles me. Of course we write source code to communicate
with other people. That's why we develop clear, elegant, orthogonal,
unambiguous codes. It's no use pretending that natural language is
clear or elegant or orthogonal or unambiguous. It ain't. It's a
complete mystery that it's usable for communication at all.

LisP in its cleaner forms (yes, Schemers, you may take a bow) is a
pure language of communication in which it is difficult to write a
line which is not poetic, transparent, acute.

I can read Robert's 'tongue in cheek' function and immediately
appreciate its force. His second version, with LOOP, is to me much
less clear.

Scott Anderson makes the same argument:

In article <ANDERSON.95Jul25175039@earhart.cs.umass.edu>,
>
>Simon has a good point.  Common Lisp has several "sub-languages" that are
>completely different from Lisp.  One is the LOOP macro, with its keyword
>syntax, and another is the FORMAT language.  (Quick, what does
>"~{~@~a~~^,~}" do?)  
>
>First, is LOOP simple and clear?  Yes, I think simple stuff is clear:
>
>    (loop for i from 1 to 10 collect i)
>
>versus the following or any of its variants
>
>    (let ((list nil)) 
>       (do ((i 1 (1+ i)))
>           ((>= i 10) (nreverse list))
>        (push i list)))
>
>I'll grant that complicated uses of LOOP can be unclear, but I think
>that's the nature of the problem, not the syntax of LOOP.

But iteration rarely produces a clear statement of a complex problem.
Recursion is almost always clearer for the reader (let the compiler
take care of the efficiency issues):

(defun series (limit (n 1))		;; Cambridge LISP, not CL
					;; I *HATE* keywords!
  (cond ((eq n limit) (list n))
	(t (cons n (series limit (add1 n))))))

You claim this is not clear? You claim that interpreting the above
needs special knowledge? Well, of course it does, and anyone can see
it does. But interpreting (loop for i from 1 to 10 collect i) also
requires special knowledge. What will it return? A list? Where does it
say so? What order will the list be in? It's superficial clarity hides
deep ambiguity.

Most importantly, it is *another* special language. So the LisPer who
uses the loop macro needs not one special language, but two. They're
quite different and have quite different grammar, yet
loop-macro-language provides precisely no additional expressive power.
It's simply introducing a new area for confusion and error.

Back, briefly, to Scott:

>If LOOP can be simple, what about Lisp "design philosophy," as Simon puts
>it?  What's the point of all those parentheses, if we can do without them
>in languages like LOOP?
>
>I believe that the point of Lisp syntax is to write code in a form that is
>easily written by or analyzed by a program, particularly a Lisp program.

No: that's to put the cart before the horse. Yes, it's a fortunate
side-effect that making a language clear and elegant for human beings
to understand also makes it easy for machines to analyse. 

It's easy to analyse because it's easy to analyse. I spend a great
deal of my time analysing programs, and I appreciate clarity very
greatly. 

>I disagree with Simon about simplicity, clarity, and even aesthetics. I
>think Simon's new subject for this thread, "aesthetics," isn't right.  I
>don't mind Lisp's parentheses--I kinda like them--but they're there for
>function, not beauty.

But function *is* beauty, in code just as in physical structure. We
appreciate a suspension bridge because it resolves the forces on it
with the least possible use of material, the clearest, simplest shape.
Lists *are* that clearest, simplest shape for containing meaning.

(with (one (single) 
	   (orthogonal) 
	   (building block)) 
      (the delimited list))

we can build what those who use languages which lack a clear
mathematical basis require a 

wholly baroque( and arbitrary)
{
     collection( &of, widelyvarying, syntactic->junk);
}

Seriously: which do you prefer? Which do you find easier to read?


-- 
------- simon@rheged.dircon.co.uk (Simon Brooke)

			-- mens vacua in medio vacuo --

