Re: Relative merits of Lisp-1 vs. Lisp-2?



Ron Garret <rNOSPAMon@xxxxxxxxxxx> writes:

In article <uirna58pk.fsf@xxxxxxxxxxx>,
Kent M Pitman <pitman@xxxxxxxxxxx> wrote:

A number of options were provided for "customizing" the language, but they
came to be properly seen, as Pascal astutely observes here, as big-switch
ways of turning the language into an implementation substrate for another
language, not really as customizations of the current language.

Sure. So? Isn't that (being an implementation substrate for other
languages) one of the things CL is supposed to be for?

Not at the expense of program combination, no.

Common Lisp's design just about everywhere presupposes the desire to
be able to load cooperative modules that were not written with
specific knowledge of which would be useful to which others.

That is, Common Lisp's design was a SPECIFIC reaction to the sudden
shift from small-address-space situations like Maclisp served (where
you couldn't load much into a Lisp at all just because 256K words was
darned small and we all knew it, we just also knew that a megaword of
memory (called a "moby") cost about a million 1970's-dollars (the
equivalent of even more money today), so we made reasonable
compromises to tolerate the small size) to the large-address-space
situation where you could suddenly get several megabytes small numbers
of thousands or tens of thousands of dollars. That shift meant that
it was possible to co-load various large applications that had been
independently written and they could hope to plug and play together.

If you go back and study the history, you'll remember that the reason
Common Lisp came about at all was that DARPA was tired of funding
incompatible efforts and it wanted to build applications where the parts
were developed separately but could be put together. For this, it was
leaning toward Interlisp until the Maclisp-subfamily of dialects said
"we're really all the same, and we'll prove it by joining to be Common Lisp".
That design was a strong move to acquire DARPA's predisosition to accept
Interlisp as the larger installed base.

DARPA would never have bought Common Lisp if we'd said "it will have
many features, but one of them will not be that applications can expect
to plug and play without prior cooperative communication to assure they
aren't stepping on each others' toes."

Sections like

11.1.2.1.1 Constraints on the COMMON-LISP Package for
Conforming Implementations
http://www.lispworks.com/documentation/HyperSpec/Body/11_abaa.htm

11.1.2.1.2 Constraints on the COMMON-LISP Package for
Conforming Programs
http://www.lispworks.com/documentation/HyperSpec/Body/11_abab.htm

are testimony to the intent of the vendors not to have one program step
on another.

That doesn't mean that we didn't intend to be an implementation
substrate. It means we didn't intend to be ONLY an implementation
substrate, which is a lot of what Maclisp had started to become--a
veritable Tower of Babel where there were pockets of compatibility,
but a number of packages were not cross-compatible.

The Lisp Machine's invention of the package system refined the clumsy
notion of separated obarrays in Maclisp. Obarrays gave the technical
power of a package, but were so clumsy to use that almost no one used them
other than the compiler itself, which had a special obarray that separated
it from user code so that executing user code in the compiler didn't break
the compiler. But the fact that there was no syntax for them meant they
really weren't usable by regular usables.

Maclisp was also not really lexical in any serious way (other than the
compiler's propensity for simply ignoring the dynamic "semantics" of
variables in the interpreter). Interpreted variable bindings had dynamic
scope, but compiled bindings had sort-of-lexical scope (other than that
closures didn't get created except in a hodgepodge of specialized
circumstances).

Maclisp was historically important for many things it did, but perhaps one
of its lasting contributions was the number of errors made in its design
that led us to do things better in the future...

.... if we remember the lessons.

Otherwise, well, I suppose the obligatory conclusion is:

Those who don't learn from the lessons of (programming
language design) history are doomed to reinvent Maclisp.


It's strictly true what you say Ron that it would implement the feature you
want, but it does so at the expense of any other uses of that switch, since
such uses are likely to be incompatible. Consequently, the nightmare we
had in the late 1970's with libraries only loading if they were loaded with
other "culturally compatible" libraries is likely.

No. There are certainly ways to shoot yourself in the foot with
*combination-hook*, but it takes only a tiny modicum of programmer
discipline to avoid them. The situation is no different from all the
other global variables controlling the behavior of various aspects of
the system now.

The other variables you cite are problematic at best already, but are
marginally justified because everyone knows about them. They are there
in the core language, and anyone learning the language knows to bind
things like *print-level*, *read-eval*, etc. if they run an application
that might be affected.

The same can simply not be said about an implementation extension that
is equivalently powerful. A portable application will not know to protect
itself.

This situation of independent module design in CL is inevitably
characterized by the Prisoner's Dilemma. It is a critical aspect of
that dilemma that
* the prisoners do not communicate
* the prisoners have knowledge of all the choices
* the prisoners know the scoring effect of them making choices in isolation
and the scoring effect of others making choices in isolation

The CL community shares both rules and style guidelines that embrace and
exploit reasoning in the style of the Prisoner's Dilemma as applied to
decisions about how to affect global variables, how to affect syntax, how
to do export of symbols, etc.

In the case of an implementation extension not shared by the entire
community, you have non-communication among prisoners but incomplete
knowledge about choices and scoring, so unprepared applications are
doomed to be improperly designed because they cannot protect
themselves.

If anything, I'm _more_ comfortable with *read-eval* and *print-length*
being characterized as an "attractive nuisance"
[ref: http://en.wikipedia.org/wiki/Attractive_nuisance ]
and having people be more conservative about their uses than saying that
these are existence proofs of that it is ok to not worry about the
attractive nuisance potential of something like a *combination-hook*.

There is certainly value in these special variables, however I think it's
still important to stay on guard for their Dark Side and to develop good
strong programming guidelines that work to diminish the ill effects.

While it might be possible for you to develop a theory of how this could
be done for *combination-hook*, you haven't done so, so I cannot critique
your theory. It is not reasonable in my theory of public debate for you
to claim that the mere possibility that you could develop such a theory of
good style is enough to trump my concern that you might not. That's like
saying it's fine to build nuclear power plants without regulation because
I can't prove that every way you could do it will lead to a problem. It's
sufficient in my book that there are reasonably forseeable ways you could get
to a problem and beyond that it's your burden in wanting to promote the idea
to show that these cannot happen. You've not done that.

In case anyone's curious, since it's ill-documented (and would be even if
I'd get off my tail and get the Maclisp manual online, as I keep being on
the verge of doing if I weren't so busy with work), the latter-day features
included:

* a switch to allow hunks [a sort of n-ary cons with (cxr n hunk) being
the accessor and hunks being like a "cons with a middle" so that the
operations car and cdr were slot 0 and 1, but other slots were after
allocated in what visibly seemed like "in between" (even though
internally they were "at the start"] being able to masquerade as EITHER
a cons (that is, the "middle" - slots other than 0 and 1 - was invisible
to most programs and they answered true to consp) or else as a special
opaque type that had a "handler" so that we could experiment with
class systems.

* strings were either symbols with a special property (sometimes called
fake strings) or were specially hacked things that stored contents
rationally (instead of in "pname" (symbol-name) format, which was
in that language a linked list of 36-bit integers [it was a 36-bit
machine], each integer having 5 7-bit ascii characters in it, and access
time growing badly as the strings got long).

I think there were other features like this that were incompatible, too,
but those are the big ones. People diverged into camps who liked one or
another paradigm, but you couldn't co-load all of the support. It's a bad
plan for a unified community.

I don't understand this at all. Leaving aside my impression that these
things are just incredibly bad ideas (they seem to be just
non-transparent efficiency hacks), how do they result in
incompatibilities?

By creating situations that were mutually incompatible when loaded together.

That's probably an overbrief answer. But I don't have time for something
better.

Almost better, even though it seems more special purpose, to have
*open-open-funcall-mode* [and to somehow explain away lambda and setf
as exceptions] because at least an implementation with that isn't tempted
to say "oh, there are OTHER things you could do with *combination-hook*
and then to develop warring factions.

I think you're being paranoid. I don't see a lot of wars breaking out
over the use of *readtable*. Why should *combination-hook* be any
different?

First, *readtable* is bound per-file. That creates some partial boundary
against problems.

Second, *readtable* is indeed overpowerful and people routinely talk about
the issue of changes to the readtable from one application infecting another.
So it's not a good model of safety.

Third, *readtable* affects readtime, not runtime, and it's
traditionally easier to isolate that. It's rare (not impossible, just
rare) for a reader for one module to need to call code from another
independently-written module. A huge percentage of all custom reader
applications assume that they will only see or call code from their
own module while in recursive calls, so that doing (let ((*readtable*
*my-readtable*)) (read)) is often extremely safe.

But, in fact, speaking now to the exceptions (and elaborating on my
second point), it's a common for people to have problems where one
readtable contains some readmacros you need and another contains
others because indeed the modularity that CL promotes is not 100%
optimal here. You might sometimes wish for something more like a
dynamic chain (a search list of sorts) but then applications would
have to be debugged on a per-application basis--it wouldn't be
possible to prove that an individual module works without knowing that
others were not involved. And that's where this whole discussion
began--the desire to avoid that.
.



Relevant Pages

  • Re: Why return None?
    ... > That extend doesn't work for strings and tupples is irrelevant. ... If lists were being designed from scratch today, ... A "greenfield design", an entirely new language designed from scratch, ...
    (comp.lang.python)
  • Re: (Falsifiability is binary) Re: Textbook text candidate
    ... recognise design in the abstract without reference to the methods ... volume and strength of the evidence, ... You have a linik to a language aquatitional page. ... and right up and down why would aliens not use a similar form. ...
    (talk.origins)
  • Re: [Lit.] Buffer overruns
    ... this is a long rant about the links between language ... Both to some extent but definitely worse within the C community than in, ... >> culture (I am contrasting Ada and C only because I have a lot of first ... culture of low level design that it has unwittingly fostered. ...
    (sci.crypt)
  • Re: (Falsifiability is binary) Re: Textbook text candidate
    ... It adds nothing to the question of idetifying DESIGN. ... You have a linik to a language aquatitional page. ... Imagine if you will the way Hieroglyics are written left and right up and down why would aliens not use a similar form. ... To snidely asume noone has looked for primes in DNA belies the intense scritiny that undergraduagte scramble for thesies. ...
    (talk.origins)
  • Re: Speculative Design Hypothesis (with predictions) 2nd draft
    ... I'm not saying that DNA is a language ... natural languages has nothing to do with design. ... bat wings - therefore bat wings "had to be" ... So far, I'm the only person to mention the blue duck, so it's unfair of ...
    (talk.origins)

Loading