[comp.lang.scheme] To Lisp, or not to Lisp; that is the question.

jonl@lucid.COM (Jon L White) (03/08/91)

I've been most amused by the argumentations recently about why Scheme
should be considered a descendent of Algol-60 and not of Lisp.  Clearly,
some recent converts to the fold really haven't grasped what Lisp is
all about, and would probably even have great difficulty mounting a 
credible attack on the thesis that "C is dialect of Lisp".

First off, I appreciated Jinx's listing of "interesting", typical
attributes of Lisp dialects:

    Date: 27 Feb 91 02:30:28 GMT
    From: "Guillermo J. Rozas" <jinx@zurich.ai.mit.edu>

    Well, what makes a Lisp?  Let me suggest a few requirements.
    1. List processing.
    2. Programs that look like data.
    3. Objects with unbounded extent and automatic storage management.
    4. EVAL (making use of 2).
    5. Powerful syntactic extension facilities that make use of 2.
    6. Call by value.
    7. Imperative constructs.
    8. Functional style encouraged, or at least not discouraged.
    9. Latent types.
    10. Generic arithmetic, with integers not restricted to the word size
    of the machine.
    11. Interactive development enviroments.

but I too would have added:

    0. incremental "on-the-fly" definition and re-definition capabilities


To some of us, this has long been a dominating characteristic up there
along AutomaticStorage (GC), Macros (in the same language!) and the big 
seven: CAR, CDR, CONS, ATOM, EQ, QUOTE, and LAMBDA.   Of course, it may 
be difficult to see how to effect Jinx's item 4 without this kind of 
incrementality; but as subsequent discussion about the programmability 
of EVAL in terms of documented primitives shows, the existence of an 
interpreter can't be fundamental.  Gosh, there even exist interpreters 
for the infamous Machine-Independent Machine Language (you know, the 
language that comes bundled in with most Unixes, and that is generally
known by a one-letter acronym beginning with C.)

Indeed, the messages about the environmental difficulties of LOAD strike 
right to the heart.  Do you know of any conventional computer language
in which the compiler's symbol table is not only present in the runtime
image, but it is effectively a first-class data object? (and I DON'T 
mean "environments" -- I mean symbols).  So, I would say, if you wan't 
to keep Scheme in the Lisp family, don't break LOAD by turning it into
INCLUDE.


The trouble with explicit listings of features, however, is that there
will always exist some Lisp out there somewhere that will lack, or violate,
any given feature.  That is as it should be.  In a nutshell, Lisp comes 
from the "ball of mud" family, whereas many recent languages are of the 
"crystalline gem" variety.  What's the difference?  Well, the most enduring 
purpose to which Lisps have been put is in the experimentation with new 
ideas in programming languages.  What, you don't like the slowness of 
latent types (runtime type markers and dispatches)?  then simply stick a 
DECLARE statement taken directly out of FORTRAN II into the language and 
make it work like Fortran; now you have a language that is _both_ latenly 
typed and statically typed, with the advantages (and somtimes the 
detriments) of both.  What, you don't like full stack retention just for 
making a simple parametric function? then add in the rule of "closure'ing"
only over the lexically apparent variables, and you have a lexically scoped 
Lisp as well! [well, in truth, as George Carrette pointed out, MacLisp was,
and Common Lisp is, both dynamically scoped and lexically scoped for most 
intents and purposes;  but it is really only for the semantics of first-
class functions -- "closures" where the difference matters in a big way.]
What, you have a 640K PC, and find that you can't even load the 11MB image 
that your compiled "hello world" application turns into?  then just add a 
DEFSYSTEM-like facility and call the TREESHAKER to turn it into a 300KB 
image ("TREESHAKER" == a garbage collection from "real" roots; just grab 
your application by it's roots and shake very hard so that all of the 
unattached pieces fall off.  Maybe the "defsystem" has to do a little 
pruning of the tree first.)


So.  Flexibility.  The Artist's "ball of mud" which is plastic in his
hands, to be pushed and molded in any direction profitable; which retains
its essential malleable character no matter how badly deformed; stomp
on it here, and it Lisp pops its head up over there.  But what about the 
conventional languages?  take that "diamond" of a language, Algol; it's 
beautiful, it's perfect!  but touch it's design in any way and it 
immediately shatters into a million little pieces.   Change just one 
tittle of your C code on just one line somewhere -- and it's forget it
Charlie, have to re Make the world all over again, Big-Bang de-novo.
Or, just try to throw Garbage Collection into your basic fragile 
"strongly-typed" computer language, where datatypes are only a dream 
in the mind of the compiler, and watch your address space silt-up with 
the orphans of "conservative" or heuristic reclamation approaches.

[Proponents of pure "statically-typed" languages don't always have a 
consistent reason as to why they reject the very minor modifications 
necessary to make _accurate_ GC possible in their language; but there 
are always two ruses they can fall back on: (1) runtime-typing seems 
involved, and that adds one instruction to some compiled-code sequence 
somewhere, so the performance would be unaccaptable, or (2) "our language"
supports real-time embedded systems -- such as Jet aircraft wing 
controllers -- and programs must never be side-tracked by an excursion 
into an unplanned GC.  Brittle.  Indeed, it was infinitely easier to add 
Fortran's DECLARE into Lisp -- as my own work with PDP10 MacLisp back in 
1971 to 1973 showed -- than it is to add even the simplest of the Lisp 
characteristics to ADA.  And ADA was even planned with the thought of GC 
in mind!]

Anyone for ADA++ ?

But one more historical fact places Scheme squarely within the Lisp family.
For years, during and after its genesis, its father -- Gerry Sussman -- 
directly owned up to his paternity and claimed it as one of his own "Lisp" 
dialects (he had engendered several during the early 1970's).  And the 
mid-wife to its birth -- Guy Steele -- says so too.  With such endorsements
... well, if it isn't clearly obvious that Scheme is a dialect of Lisp, 
then clearly we must extend the meaning of "Lisp" to include it, to adopt 
this fertile child of the family.


To give credit where credit is due, the analogy of Lisp as a "ball of mud"
 -- because of its ability to absorb the good ideas of other programming 
languages (e.g, Fortran, ECL, Algol, etc.) -- comes from Professor Joel 
Moses of MIT.  He coined it at a time when MacLisp was being molded to fit
the requirements of that symbolic algebra manipulation system which we all 
know and love as MACSYMA.



-- JonL --

kend@data.UUCP (Ken Dickey) (03/10/91)

jonl@lucid.COM (Jon L White) writes:

JUNX>    Well, what makes a Lisp?  Let me suggest a few requirements.

	<deleted>

>but I too would have added:

>    0. incremental "on-the-fly" definition and re-definition capabilities


A small, but important clarification: let's seperate "language" and
"programming environment" issues.  Compilation, loading, debugging,
system build, etc. are very important for usability but are not part
of a programming language.  Very rarely are standard interfaces to
programming environment services even defined 8^(.

Don't get me wrong, I think that Jon's points are well taken ("Lisp"
is not just a family of languages but a way of `doing business').  I
am just a nit-picker who would prefer to see the discussions on this
thread about EVAL, LOAD, INCLUDE, etc. to be posted under the heading
of "standard interfaces to programming environment services", rather
than "language features".

-Ken Dickey					kend@data.uucp

welch@sacral.cis.ohio-state.edu (Arun Welch) (03/11/91)

From: kend@data.UUCP (Ken Dickey)
>jonl@lucid.COM (Jon L White) writes:
>>but I too would have added:
>>    0. incremental "on-the-fly" definition and re-definition capabilities
>
>A small, but important clarification: let's seperate "language" and
>"programming environment" issues.  Compilation, loading, debugging,
>system build, etc. are very important for usability but are not part
>of a programming language.  Very rarely are standard interfaces to
>programming environment services even defined 8^(.

Incremental definition and re-definition might be used heavily by the
environment, but some of us depend on them being part of the language
too. Most of our larger systems (and a fair number of our smaller
ones) build functions and data structures on the fly and
evaluate/compile them on the fly too. Having these part of the
language definition is why Lisp has been used so much in AI. For
example, it's not unusual to generate a mapping function for MAPCAR,
or to generate a class definition, make instances of the class, and
run the program based on that class. Or, for a more concrete example,
an interface builder I wrote for an early version of CLIM generated
code, which the user typically ran while debugging the interface, at
the end of which those data structures were converted back into
human-readable (OK, mostly human-readable, no one can read gensyms :-)
form for saving out. It would have been impossible/very difficult to
do without incremental definition, instead it took only about 2
weeks from prototype to system.

...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@cis.ohio-state.edu

jeff@aiai.ed.ac.uk (Jeff Dalton) (03/12/91)

In article <455@data.UUCP> kend@data.UUCP (Ken Dickey) writes:
>A small, but important clarification: let's seperate "language" and
>"programming environment" issues. [...]

>Don't get me wrong, I think that Jon's points are well taken ("Lisp"
>is not just a family of languages but a way of `doing business').  I
>am just a nit-picker who would prefer to see the discussions on this
>thread about EVAL, LOAD, INCLUDE, etc. to be posted under the heading
>of "standard interfaces to programming environment services", rather
>than "language features".

It is a useful distinction, but I think it's a good idea to remember
that some of the reasons for making it are political.  (Not all of
them, of course.)

In the Lisp community, the distinction is often used in the defense
of Lisp, to make it seem more like other languages, more static and
declarative, less dynamic, less a matter of side-effects.  For example,
in response to a claim that the Lisp programmer's ability to redefine
functions at run-time was a Bad Thing, an answer might be to say that
it was part of the environment not the language (just like it might
be part of some C environment).  That's not the answer given for
Scheme, but it's the kind of answer that's sometimes made.

But the language / environment distinction is also used _against_
Lisp.  For example, I've heard people claim that no one really likes
Lisp as a language.  It's the the _environment_ they like.  [I think
this claim is false, by the way.]  As the environments for other
languages get better, a slight variation on this argument will, I
suspect, be used again and again.  There's no reason to use Lisp for
this project, we'll be told, because we can get the same advantages
using <insert the name of your favorite C or C++ interpreter /
environment> without any of the disadvantages.

This is not to say we shouldn't distinguish the language from the
environment.  If anything, we need to pay more attention to it.  We
(that is, those of us who want to use Lisp and want Lisp to succeed)
need to make Lisp environments better.  We also need to identify and
emphasise those advantages of the language that are not just
environmental.

However, we should not let this mislead us into relegating too
much to the environment.  Different implementations of the language
can provide very different environments.  So if something is classed
as environment, it might not be present in all implementations and,
consequently, it can't be used in portable code.  If we start to
require various environmental features, the whole language / env
distinction makes much less sense except as an aid to conceptual
simplification.

I do not agree that EVAL is environment.  EVAL might be provided as
part of the environment in Scheme -- because it's not part of the
language.  But that does not mean it is inherently environmental.
In most Lisps, it is part of the language.  In this it is different
from LOAD.  EVAL is not just another way to get programs into
execution.  It is not just an alternative to LOADing them, or
typing "lisp <filename>" to the shell.

-- jd

jonl%kuwait@lucid.COM (Jon L White) (03/12/91)

In   Volume 3 : Issue 154   both Arun Welch and Jeff Dalton jump to
the defense of certain Lisp aspects as being "hard core" rather than
simply "soft" environmental decoration.  Both of these were in response
to Ken Dickey's minor criticism in    Volume 3 : Issue 153  in which
he separates out the "incremental" nature of Lisp from the language
definition proper.

First, let me say that I wholeheartedly agree with Arun and Jeff; but
their rebuttal is not so much a refutation of Ken's comments as the
other side of a coin.  As Ken himself said "... Jon's points are well 
taken (`Lisp' is not just a family of languages but a way of `doing 
business')."  Part of that "way of doing business" has been an explicit 
catering to the prototyping developer; but another part has been the 
mathematical reflective nature of languages.  See for example Brian 
Smith's work on 3-Lisp.

Here are the kinds of comments I would have made on this topic, and in 
fact did make privately on another channel:

  This is a very delicate question; I claim that there is no easily
  productive boundary between these concepts and "the language".  True,
  there are some things that haven't yet become part of the Lisp
  language that are truly "environmental" -- I would limit these to
  the OperatingSystem type things that other languages have to interface
  to also, such as file path names, the file system in general, X, 
  "windows", GUI's and persistent object stores and so on.

  But is APPEND part of the language of Lisp, or is it merely an
  electable function in the environment?  How about PRINTF and FSCANF
  for C?  The reason I think that the answers for C are easier and
  clearer is that Lisp, in constrast to C, is a highly reflective
  language; the compiler and loader are "first-class" and resident
  from the viewpoint of a "typical" Lisp programmer, and this shapes
  one's attitude of what is "in" the language very much.  Again, it
  is still Lisp, in my opinion, if you elect to leave the compiler 
  out etc.; but it just ain't C if you throw these things into C
  (i.e., it is UNIX, or "Some Wonderful C debugging environment", 
  or ..., but it is not what has come to be known as C.)

  Thus the "interactive" versions of C and Fortran are not even billed 
  that way -- they are the addition of an interactive debugging
  environment to a kernel C or Fortran language.  And perhaps that
  is why one is tempted to think of such features as being merely
  an "environmental add-on" for Lisp rather than as a fundamental
  reflective feature.

In addition to these comments, one must recall that for years the
obstinate barrier to porting C applications from one vendor's Unix
to another's has been the clear lack of standards in what has come
to be called the "runtime library".  Is the "runtime library" merely
an environmental issue?  I would say no; and no good purpose can be 
served by excluding these items from a standardization process simply 
because they fall outside a "hard core" kernel language definition.
Recall Dalton's concern that classifying too many important parts
of a language/world as environment drastically reduces portability.


Finally, recall that Common Lisp's fate has been forever altered in a 
significant way by the adoption of CLOS.  Fewer places could make the 
reflexive nature of Lisp more evident than the so-called Metaobject 
Protocol (or, the emerging proposals for a standard such protocol).  
CLOS written in CLOS is not just a metaphor now, but an essential 
language necessity.  We of the community that foisted this humongous 
system onto the Lisp world (Common Lisp world), did not do so just 
for the idle intellectual curiosity of a reflexive language with a 
metacircular definition, but rather we did it because of the history 
in the Lisp world of wanting to "tailor" the system-defined facilities 
(or, the standardized environment???) in an application dependent way.
Finally, now, we have a reasoned and principled way to permit such 
"tailoring" without adding a 1001 ad-hoc "hooks".

As a "way of doing business", Lisp is definitely more meta.


-- JonL --



P.S. Ken's message referred to me as "Jon"; my full name is John L. White,
     but everyone refers to me as JonL (pronounced "John-ell").  There is
     another famous John R. White in the world of computer languages, and
     confusingly enough, during 1983-1985 when we both worked at XeroxPARC,
     we had offices within 50 feet of each other.  I don't actually know
     if anyone refers to him as "John R".


P.P.S. Someone mentioned to me privately that  SML (Standard ML of new 
       jersey?) and Modula-3 are statically-typed languages with Garbage 
       collection.  Right.  My original message was referring to 
       "conventional" computer languages, and alas not even APL nor 
       SmallTalk fall into that blessed category (and they have had true 
       garbage collection just about as long as Lisp has.)  I also know 
       of a research group at UmassAmherst that is putting GC into a
       strongly-typed "conventional-looking" language, and there is a
       sense in which Modula is "conventional-looking";  More power
       to them!   Reports of "heuristic" GC for C++ have been confirmed
       (by published research);  reports of "accurate" GC, however, are 
       premature.

pcg@test.aber.ac.uk (Piercarlo Antonio Grandi) (03/14/91)

On 11 Mar 91 18:23:32 GMT, jeff@aiai.ed.ac.uk (Jeff Dalton) said:

jeff> But the language / environment distinction is also used _against_
jeff> Lisp.  For example, I've heard people claim that no one really likes
jeff> Lisp as a language.  It's the the _environment_ they like.  [I think
jeff> this claim is false, by the way.]

Actually I think exactly the opposite; I love Scheme (and Lisp) as
*languages*, and I think that their usual environments are regrettably
overdone and isolated from the larger environment in which they are run,
and so on.

jeff> I do not agree that EVAL is environment.  EVAL might be provided as
jeff> part of the environment in Scheme -- because it's not part of the
jeff> language.  But that does not mean it is inherently environmental.

EVAL is the "compiler", really. An argument can be made that the 'C'
environment is the whole of Unix, yet, so maybe since you can after all
in 'C' write things to a file and then 'system("cc -c ...");' you can
claim you have eval in 'C', in its environment, just like Scheme.

jeff> In most Lisps, it is part of the language.  In this it is
jeff> different from LOAD.  EVAL is not just another way to get programs
jeff> into execution.  It is not just an alternative to LOADing them, or
jeff> typing "lisp <filename>" to the shell.

It depends on whether you look at the Lisp implementation as a virtual
machine on its own, or on whether you see it as amodule of the
environment of the underlying OS. In the former case, EVAL is indeed
part of the 'language' :-).


--
Piercarlo Grandi                   | ARPA: pcg%uk.ac.aber@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk

kend@data.UUCP (Ken Dickey) (03/14/91)

Let me attempt a clarification...

jonl%kuwait@lucid.COM (Jon L White) writes:

>... Is the "runtime library" merely
>an environmental issue?  I would say no; and no good purpose can be 
>served by excluding these items from a standardization process simply 
>because they fall outside a "hard core" kernel language definition.

I agree.  The question is how to go about it (see below).


>Recall Dalton's concern that classifying too many important parts
>of a language/world as environment drastically reduces portability.

I don't see that "the classification" (making distinctions) reduces
portability.  It is the lack of standards that reduces portability!  I
have been taking a "constructive" view in trying to separate standards
for "language", "runtime system library", "development system", etc.,
*all* of which are important. 

My motivation for making such distinctions is that I want to see
standards arise just so that I can write portable Scheme code in
industrial environments.  At the same time I am sensitive to
experimental/research implementors.  Thus when the question is asked
"What is Scheme?", or "What something can be called `Scheme'?"  I
would like a reasonably low entry fee (level 0).  I certainly want to
be able to add new data types (e.g. Windows) to Scheme by augmenting
the runtime library--I don't feel that this changes the "language".
However, when I want to write portable Scheme code in industry, I want
to use an implementation which conforms to "the portable development
standard" and guarentees base-line functionality and interfaces (level
5?).

By making the distinctions, I think that we can have "portable
language", "portable runtime", and "portable development services"
while still being able let people experimenting with small or "rad"
implementations be able to call something `Scheme'--and have that mean
something. 


>P.S. Ken's message referred to me as "Jon"; my full name is John L. White,
>     but everyone refers to me as JonL (pronounced "John-ell"). 

My apologies, JonL!


-Ken					kend@data.uucp
	[People sometimes call me "Kend"---^]

jeff@aiai.ed.ac.uk (Jeff Dalton) (03/16/91)

In article <458@data.UUCP> kend@data.UUCP (Ken Dickey) writes:
>>Recall Dalton's concern that classifying too many important parts
>>of a language/world as environment drastically reduces portability.
>
>I don't see that "the classification" (making distinctions) reduces
>portability.  It is the lack of standards that reduces portability!  I
>have been taking a "constructive" view in trying to separate standards
>for "language", "runtime system library", "development system", etc.,
>*all* of which are important. 

It is the lack of agreement between implementations that reduces
portability.

One reason for classifying something as "environment" as distinct
from language is to allow implementations of the same language to
provide different environments.

Having a separate environment standard may be a good idea, but
it would still be the case that implementations of the language
would not have to conform to the environment standard.

>I certainly want to be able to add new data types (e.g. Windows) to
>Scheme by augmenting I don't feel that this changes the "language".

It is possible to make a number of different distinctions between
"langauge" and "library", just as it is possible between language
and environment.  In C, for example, arithmetic is not part of
the library.  In some Lisp, it just might be.

>However, when I want to write portable Scheme code in industry, I want
>to use an implementation which conforms to "the portable development
>standard" and guarentees base-line functionality and interfaces (level
>5?).

It helps to keep the number of possible permutations small.

-- jeff

jeff@aiai.ed.ac.uk (Jeff Dalton) (03/16/91)

In article <PCG.91Mar13191008@aberdb.test.aber.ac.uk> pcg@test.aber.ac.uk (Piercarlo Antonio Grandi) writes:
>On 11 Mar 91 18:23:32 GMT, jeff@aiai.ed.ac.uk (Jeff Dalton) said:
>
>jeff> But the language / environment distinction is also used _against_
>jeff> Lisp.  For example, I've heard people claim that no one really likes
>jeff> Lisp as a language.  It's the the _environment_ they like.  [I think
>jeff> this claim is false, by the way.]
>
>Actually I think exactly the opposite; 

Ok, but I didn't have you in mind for this example in any case.

>I love Scheme (and Lisp) as *languages*,

It's good to see we agree on some things.

>                                         and I think that their
>usual environments are regrettably overdone and isolated from the
>larger environment in which they are run, and so on.

I am a bit puzzled by this.  Most of the Lisps I use have a fairly
minimal environment (trace, step, a debugger); most of my programming
environment is in the editor.

Moreover, it's hard to see why these environmental features make
the environment overdone.

>jeff> I do not agree that EVAL is environment.  EVAL might be provided as
>jeff> part of the environment in Scheme -- because it's not part of the
>jeff> language.  But that does not mean it is inherently environmental.
>
>EVAL is the "compiler", really. An argument can be made that the 'C'
>environment is the whole of Unix, yet, so maybe since you can after all
>in 'C' write things to a file and then 'system("cc -c ...");' you can
>claim you have eval in 'C', in its environment, just like Scheme.

There are a number of evaluators (interpreters and compilers) for
languages inside Lisp.  LOOP and FORMAT are large-ish examples, but
many other things can be seen that way as well.  That does not make
them part of the environment, so why should an evaluator in a language
L suddenly be environment when the language it evaluates is L rather
than something else.

You are moreover wrong about C.  For C to have something equivalent
to EVAL it is not enough that it be able to write source code to
files and then call the operating system to compile the file.
It would also have to be able to load the compiled code into the
running C program that wrote the file and called the compiler.

And even that wouldn't be fully equivalent, because code passed
to a Lisp EVAL can contain objects that cannot be written to
files.

>jeff> In most Lisps, it is part of the language.  In this it is
>jeff> different from LOAD.  EVAL is not just another way to get programs
>jeff> into execution.  It is not just an alternative to LOADing them, or
>jeff> typing "lisp <filename>" to the shell.
>
>It depends on whether you look at the Lisp implementation as a virtual
>machine on its own, or on whether you see it as a module of the
>environment of the underlying OS. In the former case, EVAL is indeed
>part of the 'language' :-).

I think you are being confused by the idea that EVAL is the compiler.
If that was all there was too it, there'd be no reason to want to have
EVAL in Scheme.

-- jeff