[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: s-exprs + prototypes



Avi Bryant quoted Alan Kay:
> "I could hardly believe how beautiful and wonderful the /idea/
> of LISP was.  I say it this way because LISP had not only been
> around enough to get some honest barnacles, but worse, there
> were deep flaws in its logical foundations.  By this, I mean
> that the pure language was supposed to be based on functions,
> but its most important components -- such as lambda expressions,
> quotes, and conds -- were not functions at all, and instead were
> called special forms.  Landin and others had been able to get
> quotes and conds in terms of lambda by tricks that were variously
> clever and useful, but the flaw remained in the jewel.  In the
> practical language things were better.  There were not just EXPRs
> (which evaluated their arguments) but FEXPRs (which did not).  My
> next question was, why on earth call it a functional language?
> Why not just base everything on FEXPRs and force evaluation on
> the receiving side when needed?  I could never get a good answer,
> but the question was very helpful when it came time to invent
> Smalltalk, because this started a line of thought that said ''take
> the hardest and most profound thing you need to do, make it great,
> and then build every easier thing out of it''.  That was the
> promise of LISP and the lure of lambda -- needed was a better
> ''hardest and most profound'' thing.  Objects should be it.

Putting aside the Lisp critique for the moment, the last bit starting from
"when it came time to invent Smalltalk" makes some sense, right up to the
last sentence, "Objects should be it."  Kay provides absolutely no support
for this conclusion - it's a completely unsupported leap.  I'm sure he's
made the argument for objects as the answer elsewhere, but that's really the
argument that's at issue.

I interpret "Objects should be it" to mean that objects as Kay conceived
them were the hardest and most profound thing they knew how to do at the
time.  And that's the exact issue we've been discussing: because a "hard and
profound" thing with a specific and somewhat arbitrarily-chosen
implementation has been hard-wired into the core of the language, if you
find those hard and profound things perhaps not quite what you want, you're
stuck with them, and their nature permeates the language and affects all the
code you write.

I've been saying that my preference is for an "easier" thing that doesn't
make as many assumptions about how I should want to write code.  Nothing Kay
says above addresses this objection.

As far the critique of Lisp goes, in this case, one man's "flaw in the
jewel" is another's syntactic sugar.  Kay dislikes the way special forms
introduce *perceived* inconsistencies -  but one of the main purposes of
special forms is to support human-friendly syntax in the presence of eager
evaluation.

The problem that Kay has raised hasn't been solved by objects in Smalltalk -
it's been addressed by the omission of macros or special forms.  This means
you need to use blocks to delay evaluation in various syntactically
arbitrary places, resulting in an inconsistent syntax: a flaw in the
Smalltalk jewel.  Is there really any significant difference between the two
approaches at all on this question, except that Lisp offers a syntactic
option that Smalltalk doesn't?

The real problem Kay has identified is nothing to do with objects vs.
functions, it's a question of the things that have to be done to support
eager evaluation.  A lazy language takes care of all of these objections.
There are some well-known reasons to want eagerness, though, as Smalltalk
acknowledges, which is why it suffers from the syntactic flaw I mentioned.
Scheme addresses this syntactic flaw with special forms.

> My next question was, why on earth call it a functional language?

Simple answer: because the surface syntax maps onto functions underneath.
This question of surface syntax is orthogonal to the underlying abstraction.

> Why not just base everything on FEXPRs and force
> evaluation on the receiving side when needed?

I'd be interested to hear other opinions about the cons and/or pros of this.
I thought something similar when I first got into Scheme - coming from a
heavily Smalltalk-influenced OO perspective - and implemented a toy Scheme
interpreter in C++.  I have a working Scheme implementation that uses the
technique Kay describes: arguments are evaluated by the called function, if
necessary.  The way I implemented it, it's still an eager language, since
argument evaluation, if it occurs, occurs as soon as the called function
gains control.  Thus the "special forms" define, lambda, set!, if, and
others are implemented as ordinary primitive functions, which satisfies
Kay's objection.

However, as I implemented it, I don't think it has any impact on the
external specification of the language - it's just an internal
implementation choice, which has no bearing on the language the programmer
uses.

So, much as I respect and admire Kay and his work, the above quote is
neither a technically meaningful critique of Lisp, nor a specific
justification for building a language around a particular type of objects.

Anton