[comp.lang.lisp] Common Lisp, SOME, EVERY...

pazzani@pan.ics.uci.edu (Michael Pazzani) (02/23/91)

In article <1991Feb22.210020.7319@aero.org> srt@aero.org (Scott Turner) writes:

>EVERY, SOME, etc., are exactly the kind of "kitchen sink" functions
>that I object to in Common Lisp.  They provide no additional
>functionality to the language, are semantically confusing, and make
>reading code difficult.
>
>A language that has a 1000 built-in functions (constructs) is doomed.
>People don't have the cognitive mechanisms to deal with that number
>and variety of mechanisms.  The result is that each person uses their
>own personal subset of the language, and a Tower of Babel results.
>Far from being "common", Common Lisp is doomed to be uncommon.
>
>					-- Scott Turner

I have to disagree with this particular example, (perhaps because
some and every are part of my working set).  Sure, you can write
equivalent code in terms of do, or recursion.  But there are common
patterns of usage of do* and recursion, that are worth having around
so they don't need to be re-invented from primitives each time.  This
makes writing and reading code much easier for me.

I'd much rather see and write
(some #'(lambda(op)(solved? (apply-op op state))) operators)
than the equivalent with do, recursion, (or mapc with a return-from).


Indeed, there are some common patterns have been left out, that
I define as macros and use extensively.  For example,
applying a function to each element of a list and consing together
the non-nil values.

(delete nil (mapcar #'fn list))
and
(let ((v))
  (mapcan #'(lambda(x)(when (setq v (fn x))
			(list v)))
	list))

are less clear to me than
(all-images #'fn list)

Furthermore, all-images can be optimized once for this particular
purpose.

Mike

delacour@margaux.inria.fr (Vincent Delacour) (02/23/91)

In article <1991Feb22.210020.7319@aero.org> srt@aero.org (Scott "TCB" Turner) writes:
>eweb@ccvax.ucd.ie writes:
> [...]
>A language that has a 1000 built-in functions (constructs) is doomed.
>People don't have the cognitive mechanisms to deal with that number
>and variety of mechanisms.  The result is that each person uses their
> [...]
>					-- Scott Turner

This, surely, is false. Many languages have more than 1000 words, and it is
no problem at all. Do you by any chance consider programming in any language 
without the libraries ? In C or Ada there are much of those, and it is no 
harm if you don't use both of them. Documentation helps you find the one
you want. It is a good thing to specify what a library does, because it 
helps portability. I have an example, just everyday life : /bin/pr
does not behave the same on Suns and Vaxes (Ultrix) : this is a pain when 
you use simple shell scripts on both machines. I do like format working 
the same way in both Common Lisps. 

	[vd]

jeff@aiai.ed.ac.uk (Jeff Dalton) (02/26/91)

In article <1991Feb22.210020.7319@aero.org> srt@aero.org (Scott "TCB" Turner) writes:
>EVERY, SOME, etc., are exactly the kind of "kitchen sink" functions
>that I object to in Common Lisp.  They provide no additional
>functionality to the language, are semantically confusing, and make
>reading code difficult.

I do not regard them as "kitchen sink" functions at all.  They are
not confusing, they make code easier to read, and (for those who
reserve their fury for _Common_ Lisp) they predate Common Lisp.
I used them in Franz Lisp, for example.  But if you prefer to 
write such operations out in-line each time, go ahead.

I think it is good practice to take useful operations and embody
them in functions.  Just imagine how much worse programs would be
if people didn't do this.

>A language that has a 1000 built-in functions (constructs) is doomed.
>People don't have the cognitive mechanisms to deal with that number
>and variety of mechanisms.

Well, I guess they'll never be able to write large programs, use GNU
Emacs or the X Window System, etc.  Yes, Emacs and X are standard
examples of "too big", and I'd rather Common Lisp were smaller (in
some ways).  But these things are by no means doomed.

>                      The result is that each person uses their
>own personal subset of the language, and a Tower of Babel results.
>Far from being "common", Common Lisp is doomed to be uncommon.

Well, of course people use their own personal subset of the language,
just as, in a smaller language, they write their own personal extensions.
So instead of one Tower of Babel (if you think that's what happens) we
may get hundreds.

srt@aero.org (Scott "TCB" Turner) (02/27/91)

Once upon a time I wrote:
>A language that has a 1000 built-in functions (constructs) is doomed.
>People don't have the cognitive mechanisms to deal with that number
>and variety of mechanisms.

A number of people have responded to this with comments of the sort 
"C has immense numbers of functions in libraries, and people deal 
with that..."

I don't think comparing Common Lisp's plethora of built-ins with
library functions in other languages is completely relevant.  For the
most part, library functions are not general programming constructs.
They perform specific computing tasks such as i/o, database retrieval,
statistical manipulations and so on.

There's no cognitive difficulty with that because there is still a one
to small mapping from tasks to functions to accomplish those tasks.
If I need to concatenate two strings in C, I can remember strcat[n].
C also has a one to small mapping for general programming constructs.
For iteration, I can remember for/while.

In Common Lisp, the mapping tends to be one to many.  Even ignoring
functions which do implicit iteration, there are roughly fifteen
iteration constructs in Common Lisp.  There are seven version of map!
(And as Michael Pazzanni pointed out, one of the most useful map
constructs isn't even represented.)  That's neither necessary or
desirable.

Part of the problem seems to be lack of restraint on the part of the
design committee.  Opening the manual at random, I see "case" and
"ccase", the difference being that "ccase" has no "otherwise" clause
and signals an error on fall-through.  Is it necessary or desirable to
have two different functions for this?  Why not have "case" signal an
error if there is no "otherwise" and fall-through occurs?  Looking at
the language, it appears that every design conflict was resolved by
adding both sides to the language.  It looks like someone grepped all
the functions out of five different AI programmers' code.

Another part of the problem is lack of organization.  While Steele's
book tries to force a framework on Common Lisp, many functions simply
fall through the cracks, or make poor fits.  (This is aggravated by
the inclusion of numerous seldom-used functions that don't truly
deserve to be an integral part of the language.  Does Common Lisp
really need "prog2"?  C'mon.)  As several people have suggested, this
could be improved by organizing Common Lisp into general programming
constructs and specific libraries.

					-- Scott Turner

miller@GEM.cam.nist.gov (Bruce R. Miller) (02/27/91)

In article <1991Feb26.213445.15460@aero.org>, Scott "TCB" Turner writes: 
> A number of people have responded to this with comments of the sort 
> "C has immense numbers of functions in libraries, and people deal 
> with that..."

Not all of them do!

> I don't think comparing Common Lisp's plethora of built-ins with
> library functions in other languages is completely relevant.  For the

Nor completely irrelevant.

> most part, library functions are not general programming constructs.
> They perform specific computing tasks such as i/o, database retrieval,
> statistical manipulations and so on.

Dont common Lisp functions perform specific computing tasks?

> There's no cognitive difficulty with that because there is still a one
> to small mapping from tasks to functions to accomplish those tasks.
> ...
> In Common Lisp, the mapping tends to be one to many. 

Hmm. I'm not too sure about your mappings, there.
Perhaps this C isn't the ultimate standard, but in the C I've got to
play with, you get two partially overlapping sets of IO functions: one
using *FILE and the other using `handles'.  It seems that every time I
wanted to write a program involving IO, 1/4 the functions I needed were
ONLY available using handles, another 1/4 ONLY available using *FILE.
What fun!

>  ...
> Part of the problem seems to be lack of restraint on the part of the
> design committee.  

Yeah, my thoughts exactly!

[Not to say there isn't a bit too much redundancy in CL, but still...]

john@mingus.mitre.org (John D. Burger) (02/28/91)

srt@aero.org (Scott "TCB" Turner) writes:
>Once upon a time I wrote:
>>A language that has a 1000 built-in functions (constructs) is doomed.
>>People don't have the cognitive mechanisms to deal with that number
>>and variety of mechanisms.
>
>A number of people have responded to this with comments of the sort 
>"C has immense numbers of functions in libraries, and people deal 
>with that..."
>
>I don't think comparing Common Lisp's plethora of built-ins with
>library functions in other languages is completely relevant.  For the
>most part, library functions are not general programming constructs.
>They perform specific computing tasks such as i/o, database retrieval,
>statistical manipulations and so on.

But that's exactly what's going on in Common Lisp.  The language
doesn't have 1000 built-ins that do the same things that C's built-ins
do.  CL gives you explicit functionality that you just don't have in C
(or many other languages).  For example, CL has:

  Many more built-in types
  Explicit run-time typing
  Multiple values
  Real macros
  An explicit representation of environments
  Packages
  A system-independent representation of the file system
    (plus logical pathnames)
  An interface to the lexical analyzer (readtables)
  An interface to the compiler
  Sophisticated condition signalling and handling
  An introspective object system

I want and use all of these things.  C may have shadows of some of
them, but they are not richly represented enough for me (please don't
provide counter-examples).  Which is not to say that some of your
criticisms of specific cases are not well-founded.  There is some
unnecessary repetition in Common Lisp, and there are constructs that
are only there for historic reasons.  I have never seen code that uses
PROG2, and I don't use SETQ, RPLACA or RPLACD.  I have no use for
LOOP, pretty printing, or most of the FORMAT sublanguage (which is
Turing complete, isn't it? :) ).  But what many people don't seem to
take into account is that CL is not just a rebinding of the same
functionality provided by C.  To be only somewhat facetious, I think
comparing the sizes of Common Lisp and C is like comparing the sizes
of C and a RISC instruction set.
--
John Burger                                               john@mitre.org

"You ever think about .signature files? I mean, do we really need them?"
  - alt.andy.rooney

mincy@think.com (Jeffrey Mincy) (03/01/91)

In article <1991Feb27.160615.8328@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes:

>I have no use for ... most of the FORMAT sublanguage (which is
>Turing complete, isn't it? :) ).  

nope, format is not turing complete.  It needs a way to assign to 
a variable (and look at the variable).  I spent some time with Guy
thinking about the turing completeness of format.

>John Burger                                               john@mitre.org


On a more serious note, I think that people are using a confused definition
of complexity.  A language that includes 1000 functions is not necessarily 
10 times more complex than a language that only includes 100 functions.

--

-- jeff
seismo!godot.think.com!mincy