From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.functional
Subject: Re: Why functional languages?
Date: 3 Oct 92 03:11:26 GMT
	<TMB.92Sep28223555@arolla.idiap.ch> <26463@castle.ed.ac.uk>
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: jamesh@castle.ed.ac.uk's message of 1 Oct 92 12:57:12 GMT

In article <26463@castle.ed.ac.uk> jamesh@castle.ed.ac.uk (James Hammerton) writes:

   With long programs, the ease with which you can read them becomes very
   important. I can imagine that with a long lisp program, checking that
   all the brackets are in the right place could become a nightmare,(though
   a good programming style would alleviate some of the worst cases), where
   the ML equivalent would allow you to forget this particular gripe.

Matching parens/brackets in large functions is no more or less
difficult in Lisp than it is in ML. In both cases, I wouldn't want to
do it without the help of my editor. Fortunately, most editors these
days support matching parens/brackets.

Indentation is different. Lisp can be indented automatically
acceptably well even by "vi". On the other hand, even Emacs can't deal
with indenting SML code.

   Also infix notation is nicer(though ML allows you to chose between infix
   and prefix notation), though I won't make a major song and dance about
   that as it is not difficult to get used to prefix notation.

I don't think "infix notation is much nicer", for the following
reason. First, you start with infix for the built-in arithmetic.  Then
people want infix for user-defined operations. Then people say, "Wait,
I don't want to use '.+.' to add matrices, I want to use '+'", so we
get user-defined overloading. Then you get into questions of how do
you scope those constructs and what happens to type-checking. By the
time you are done, you have such a syntactic and semantic mess that
neither human readers nor automatic programs can easily determine what
the rough structure of your program is.

Empirically, this simply doesn't seem to happen in Lisp-notation.
People seem to be reasonably content to write "(+ x y)" to add numbers
and "(matrix-+ a b)" to add matrices.

   The original poster was talking about the ease with which one lisp
   program could manipulate another(or itself), not readability as such.

Yes, but the general argument has been "maybe writing programs to
manipulate other programs would be slightly easier if we used Lisp
notation, but people should have to deal with that ugly, low-level
stuff". All I'm saying is that _I_ like that "ugly, low-level stuff"
even just for day-to-day programming (and I do write a lot of
numerical code).

Initially I didn't like Lisp syntax either, and there are lots of
things I positively dislike about Lisp itself (foremost, its lack of
decent module facilities and lack of static type checking). However,
after many years of programming and comparing different kinds of
syntax, I find that I prefer the straightforward, simple Lisp syntax
to just about anything else. Of course, tastes differ...

Well, once NJ/SML with "ast" comes around, I'll get a chance to
experiment. Coming up with a reasonable syntactic representation of
SML in terms of Lisp-style source code is not entirely trivial (due to
the semantics of pattern matching, currying, tuples, ...), but I have
some ideas.

					Thomas.

PS: Incidentally, I remain unconvinced that "writing programs to
manipulate other programs" would only be "slightly easier".  I would
hope that sooner or later, I could write my own syntactic extensions
to SML. For example, I would like to add some sort of syntax to make
the kinds of numerical code that I'm writing a little more
user-friendly.

In SML-with-syntax, I would certainly want to be able to add some
syntax of the following form:

fun build_array() =
    loop
       for i = 0 ... 16
       val x = f(i)
       returning array of x
    end

Now, I have a hard time imagining how I could convey to the standard
SML parser in any sort of simple and concise form that I want to
introduce some new keywords and have them parsed in some particular
way. In fact, as far as I can tell, the NJ/SML parser the way it is
provides no hooks to do this, other than re-compile the complete new
grammar with mlyacc.

I do know that this sort of thing is very simple to do in Lisp syntax,
not because manipulating the structure itself is very much easier, but
because the existing parser already knows how to _skip over_ my new
loop construct and hand it to my "macro" definition:

(define (build-array)
   (loop for i = 0 below 17
         val x = (f i)
	 returning (array x)))

(No, I'm not a fan of CommonLisp loop, but this was the first example
that came to mind...)

So, one of the major advantages of Lisp syntax is that _new_,
user-defined syntax can be handled reasonably well by old tools.
Newsgroups: comp.lang.functional