Slashdot videos: Now with more Slashdot!

View

Discuss

Share

We've improved Slashdot's video section; now you can view our video interviews, product close-ups and site visits with all the usual Slashdot options to comment, share, etc. No more walled garden! It's a work in progress -- we hope you'll check it out (Learn more about the recent updates).

A few weeks ago, you asked Kent M. Pitman about Lisp, Scheme, standards, and other things -- He's answered your questions below, at length. At such length, in fact, that only the first eleven of his answers are shown below -- expect more shortly! Thanks, Kent.

1) (just one thing (I) want to (know))?
by An Anonymous Coward

(( What ( (is)
with (all) ) of (the)
()s?
) Hmmm? )

Kent M. Pitman: This question actually got scored down to -1 and marked
as a troll question, but I fished it out of the barrel and restored it because everyone
asks and I might as well confront the issue head-on.

Ironically it's non-Lisp languages that allow and encourage you to put ()'s
in any place you want, as if there were no meaning to the introduction of gratuitous paren
groups.

3+(2*5)+7 means the same thing in an algebraic language as does
3+2*5+7. In Lisp, we write:

(+ 3 (* 2 5) 7)

This shows you the structure and means you never have to learn obscure precedence
rules that make expressions like -3! confusing in algebraic languages, where you
must learn whether it means (-3)! or -(3!). In Lisp, the parens would
show you immediately that (factorial -3) or (- (factorial 3)) was
intended.

The thing I personally like about (+ (* 2 y) x) rather than 2*y+x
is that it simplifies my editing. I'm a touch-typist and I use the emacs commands to go
forward and backward over expressions, to swap expressions, and to delete expressions very
heavily. And I don't have to reach for the mouse to manipulate large, complex expressions
because they are paren-bounded. If I put the cursor at the head of 2*y+x and say
"go forward an expression", ought this go forward over 2, 2*y, or
2*y+x? Having different editor commands to move across a sum, a product, etc. would
be unwieldy. Yet without that, I don't see how the editor would know. In Lisp, there
can't be any ambiguity because every sub-expression has its own start character, so a
single notion of "the expression in front of the cursor" or "the expression after the
cursor" suffices.

This, by the way, also answers the question of why we don't write foo(x) and
instead write (foo x). In Lisp notation, foo is an expression. In the
expression (foo x), it's a subexpression, so it's enclosed within it. Were it
outside, a text editor would not be sure if foo(x) were one expression (a
function call) or two expressions (the symbol foo followed by the list
(x)). That would make going forward over 'one expression' ambiguous when at the
start of foo(x). Should the cursor end up after the foo or after the
(x)? In other words, The natural purpose of parentheses is to enclose things, so
that's what Lisp uses them for. Avoiding ambiguity is critical to the writing of correct
"keyboard macros" in Emacs, where I might interactively write a program to do a lot of
code transformations quickly. In an algebraic language, such keyboard macros can be much
harder to write robustly.

2) It's not just me is it? by demo9orgon

After trying to "self-learn" lisp in the 80's I get this physical reaction to the word
"lambda"...a cold sweat combined with the involuntary retraction of my testicles to a
protected location in my abdomen (damn unpleasant shit)...I usually avoid that second one
by mentally going through the mechanics of "hello world" in C, or any half-a-dozen other
programming languages.

Lisp is one of those meta-languages you either learn or avoid. I write practical stuff all
the time, daily in fact, and I've never had something that required the arcane stuff in
LISP.

KMP: Actually, "hello world" in Lisp looks like this:

(defun hello-world ()
(write-line "Hello, World!"))

I don't know about you, but I find that pretty soothing.

And as to LAMBDA, one only needs use it when they find it useful. For
example, after a while, one sometimes gets tired of writing a separate function where that
function will only be used once, as in:

Whether one actually does this is purely a personal preference. Some people
like having separate named functions, some don't. Sometimes the separately named function
might have a nonsensical name, though, and it's nicer not to have to invent a stupid name
for a one-shot use.

Now, as to why it's called LAMBDA and not FUNCTION, that's just a
piece of history. You get used to it. Toward that end, I'll offer a story that will
perhaps help you put it in perspective:

Early in my not-yet career as a computer scientist, which is to say, while I was in
high school, I lived in the Panama Canal Zone. Computers were not at all common there at
the time. In fact, the place being entirely run by the US Government, there was some
weird edict that said no one was allowed to own one so that they would all be centralized
in the Comptroller's Office and not wasted in individual offices around the Zone. Our
school had to bend the rules in order to get us a computer to study. So one thing I did
while trying to learn about computers was to go downtown (out of the Canal Zone into
Panama City, in the Republic of Panama) and visit a company there who did computer work.
Of course, people there spoke Spanish, but fortunately I did, too. They showed me some of
their code, and I was immediately struck by the fact that all the language keywords were
in English.

"Doesn't that bother you?" I asked. But the person I was talking to was quite a
thoughtful person and he immediately responded this way: "Do you know how to read music?"
"A little," I said. "Have you seen the notations on music like forte, sotto
voce, and so on?" I nodded. "Does it bother you that they are in Italian?" "No," I
had to admit. His point was to make me see that it could be viewed as part of the charm
and history of the notation. He was, perhaps, unusually forgiving. But this was in the
late 1970s, when everyone who had access to computers was far too excited about just plain
having them to care about subtle issues of whose culture got too much say in the design of
a world-wide phenomenon.

So when today I look at the very few mysterious-looking terms like LAMBDA,
CAR, and CDR that still linger untouched in modern Lisp's design, I
think of them as I do those musical notations, conceptual links to a little piece of
history that I'm just as happy not to see crushed by an overeager rush to regularize and
homogenize the world--something the computer culture has done altogether too much of.

One of the primary reasons why Scheme and Lisp interest me is that they are well suited
for making applications interactively programmable at runtime (Scheme especially, due to
its small size). This is far more flexible and useful than applications which are only
extensible through heavyweight, precompiled plugins. Since the Slashdot readership tends
to be made up of people who are comfortable with programatic interfaces (unlike the
general computer-using public), why do we not see more such applications?

KMP: I think it's just an issue of education, formal and otherwise. Without being
explicitly guided, some people will try out all kinds of ways to do things, or invent them
where they're not present. But many others will simply do what they have been taught to do
without exploring the alternatives.

In the past, everything was about speed. Every instruction was precious. The focus
was entirely on "micro" efficiency. People would examine the cost of being able to
redefine something (which sometimes involves as much as following pointer indirection),
and if there was a cycle lost, the game was over. Today, hardware cache and prefetch
architectures can often hide such costs anyway, but even if they couldn't, processors run
so fast that one has time to worry not only about micro efficiency but also
macro efficiency--that is, "running smart", not just "running fast", as a way of
assuring total efficiency.

A lot of people identify Lisp as a language that is "just good for Artificial
Intelligence (AI)". Certainly Lisp is good for AI. But saying it is just
good for AI misses the point. Lisp doesn't do AI. Lisp is a programming language.
AI researchers program AI, and often their language of choice has been and continues to be
Lisp. But the important thing is that AI researchers have been banging on the door of
Lisp implementors for years, demanding the introduction and tuning of the features and
constructs they need in order to get their work done. Lisp hasn't become a mere AI toolbox
as a result of that. Rather, it has become a robust tool for addressing the world's
most complex and vexing problems. The Lisp community has a long experience with
supporting "intelligent programming", and with doing so efficiently.

Lisp's biggest problem in the past is probably that it hit its commercial peak too
early, in the mid 1980s, before most computational problems the world was confronting
were big enough to need the power Lisp had to offer. Those were the days of MacWrite and
MacPaint and Lotus 1-2-3, and it just didn't make any difference whether one used Lisp or
C for those. But for better or worse, the world has grown up around us, and the important
problems of the day are a lot more complex. I think Lisp has a lot more to offer to the
world of today than it ever did in the past.

4) The standard process
by VP

As participant in the standardization process for Lisp, what are your thoughts on
standards for programming languages? What would you like to see different in this process?
And speaking of standards, what do you think about the RAND licensing issue and the
W3C?

KMP: I think standards have served their time to provide a stable base
for people to build on, but for the modern environment, they move way too slowly to keep
pace with the speed of change in business. It took a long time to put the Common
Lisp standard together. We began in 1986, finished work in 1994, and got the actual
document to press just before the end of 1995. Getting community consensus on something
that big really does take that long, and I think it was an exercise worth doing to create
the stable base that we created, but for future evolution of the language, I think there
needs to be another way with far less overhead.

I see standards as having two components: The first is to simply cast a name into
concrete so that reference to that name will always have a clear meaning. The definition
of ANSI Common Lisp, at least for 1994, is now permanently registered. Anyone who wants
to can now conform to that definition and others will know exactly what they mean by that.
The second component is to assert an informal consensus in the community that there is a
single right way of doing things. This latter component may be useful for the foundation
(to define the initial market space), but I'm not sure it's appropriate for the library
level of the language.

For the base language, if 60% of the community wanted to do things one way and 40%
another way, the 60% got to roll over the 40%, and 100% of the community was expected to
do things in the way that won. But at the library level, if 60% want one library and 40%
want another, I'd rather 100% of the community get what they want by having some people
just do it one way and the rest of the people do it the other way. The Lisp community has
not traditionally done things that way; they've sought consensus. The Scheme community
has been even more conservative about this than the Common Lisp community, and as a result
has even fewer standardized facilities than the Common Lisp community.

The Scheme community has moved to a more loose-knit approach to break the design
deadlock brought on by the core language committee's consensus process through its Scheme Requests for Implementation (SRFI) process.
The Common Lisp community hasn't got anything quite so organized yet, but I suspect will
eventually evolve something similar.

As to the question of the W3C, I'm not a huge fan at the moment. At a prior employer,
we had the opportunity to join, but the contract we'd have had to sign made it clear that
votes among members were advisory only, and W3C itself could decide to override what
people voted on. This, to me, is not a consensus body. Furthermore, although I think
standards bodies like ANSI move in near glacial time, I don't think you can fix things by
just shortening the times. True national and global consensus just takes time, and
shortening timelines doesn't just make things move faster, it also disenfranchises people.
While I use the existing HTML, CSS, XML, XSL, and other W3C guidelines, I don't feel they
were created in a manner that I respect as proper consensus process. I think the process
was insular and rushed.

Neither am I happy with the notion of processes involving Reasonable and
Non-Discriminatory (RAND) fees being part of a standard; I think consensus standards
should only involve royalty-free (RF) technologies. I think adherence to standards should
not induce a baseline cost beyond the cost of creating the code so that the cost of
compliance with standards can closely approach zero. If there is a profit to be made on
the implementation of a standard, it should go to the implementor, not to a patent holder.
Then again, while I'm a strong proponent of software copyright, I'm not at all a fan of
software patents. Rather than seeing independent creation as infringement, I think
independent creation should be contributory proof that an idea was more obvious than
perhaps the patent office thought. I don't mind copyright because there are ways that one
can demonstrate that one did not merely copy another's work, and independent creation is a
defense.

5) Advice to Aspirants
by An Anonymous Coward

Kent, I am one of the lucky ones who programs professionally in Common
Lisp. I certainly appreciate your hard work and the hard work of everyone
else who helped to bring us the ANSI standard - which serves to reify much
of the esoteric knowledge the Lisp community has developed in the many
years since the language was born.

While I do not need to be sold on Lisp, I know many people who do not
fully appreciate the power of the language. To a large degree, this is due
to misconceptions about the language. Specifically, there seem to be a
number of what I would call 'cultural misconceptions'. Because many people
have never worked in a tightly interactive development environment with
incremental compilation, language-level introspection, and real code/data
equivalence (not to mention the differences between CLOS and what the rest
of the world seems to have come to believe is the God-given definition of
'object-oriented' programming) - they don't really 'get' what makes Lisp
so special and so powerful. More to the point, because the logistics of
developing and deploying applications in Lisp is different than what the
typical c/c++/perl/java developer knows, the hurdle to even investigating
or considering Lisp as a real possibility seems unnecessarily high.

Could you talk a bit about how those who have a feeling that Lisp might
help them with their hard problems could go about bootstrapping their way
into finding out? How would you suggest getting started? What is a
reasonable set of tools for experimentation, and where should a beginner
start with the language? (The standard is a big document!) Also, could you
give an example of the type of problem space and style of application
delivery that demonstrates that Lisp is more practical than many seem to
believe?

KMP: Well, one thing to note is that there's very little overhead to just
downloading an implementation and diving in. Not only do the major commercial vendors
like Xanalys and
Franz offer high quality, no-cost trial versions of their proprietary software, but
there are quite a number of free (non-proprietary) versions of Lisp as well. Information
about these, as well as much other useful information about Lisp, can be found at the Association of Lisp Users (ALU) web site. I've also
recently purchased common-lisp.info, which I plan
to maintain as a repository for information about Common Lisp; the site doesn't have a
large base of information yet, but it does have a list of the problem spaces in which you
might consider using Lisp.

The ANSI Common Lisp standard, effectively available in webbed form as the Common
Lisp HyperSpec, is indeed a big document (about 16MB and having about 108
kilohyperlinks
downloadable). I think it's fairly readable as standards go. But you're right that it
takes some work to get through and it wasn't really intended as a tutorial.

The ALU web site will also have pointers to books and online tutorials about Lisp.
Books by Paul Graham and Peter Norvig on the subject are very highly regarded. I think
there is always room for more, and I'm working on several, at least one of which I hope to
complete in the not too distant future; feedback
from you and others is useful to me in understanding what areas most urgently require
treatment.

One resource that some people might find useful is an article I wrote called Accelerating Hindsight: Lisp as a
Vehicle for Rapid Prototyping. This article is intended primarily for a Lisp
programmer audience, to help them articulate some of the ideas you've asked about to
others. It was not intended to be read by the audience you'd like to convince mainly
because it appeals periodically to Lispy notation that might not be familiar to them, but
it may still be of interest to the adventurous non-Lisp reader.

As your project becomes more sophisticated, and evolves from a personal toy to a
real commercial product, it also doesn't hurt to ask an expert for help. My company offers consulting services that include
helping companies manage the transition into Lisp. One of my major clients, The Software Smith approached me on just
such a basis and the result has been very exciting both for me (getting to help them
improve their system) and, I think, for them (getting to see more of how Lisp is supposed
to be used). I don't want to turn this interview into a huge advertisement, but people can
contact me for more information. If I'm
either not competent to help you or am too busy to help you, there's a very good chance I
can refer you to someone else who can help you.

6) Language feature trickle-down
by WillWare

I was a big Scheme/Lisp fan five or six years ago, but now I see most of my favorite
Lisp-like language features available in Python, which is getting a huge amount of
high-quality development mindshare these days. Some of the Lisp-ish features in Python
that spring right to mind are functions as objects, closures, garbage collection, and
dynamic-yet-strong typing, and convenient rapid-app development.

One needn't look far to find arguments that there is still something unique to Lisp that
differentiates it even from very recent languages which have had ample opportunity to
borrow from Lisp. But one rarely finds a really clear articulation of that uniqueness. Do
you think concur with the view that Lisp is still unique, and if so, do you think that
Lisp's putative advantage really is ineffable?

If there is an advantage but it's ineffable and therefore opaque to managers with
purchasing power, that would explain why Franz, Harlequin, et al have had such a rocky
road. Does the Lisp/Scheme community regard this as a worrisome issue? (Some folks on
c.l.lisp clearly don't think so, but I don't know if they are just a noisy
minority.)

KMP: I guess I think Lisp is unique, but whether it is or not doesn't
affect its usefulness as a tool. I'll enumerate some things I like about Lisp, but
Slashdot readers shouldn't assume that I'm asserting for each of these features
that Lisp has a lock on these. Various other languages surely have some of these. But I
am often heard to say: languages are ecologies. Language features are not a priori
good or bad. Rather, language features are good or bad in context, based on how well they
interact with other language features. Some of what makes Lisp what it is has to do with
the features it offers, but some of what makes Lisp what it is has to do with how the
features work together to make a coherent whole. Lifting some of these features out of
context might sometimes work, but in other cases, it might not. To get a real feel for
Lisp, or any language, I think you have to really use it.

Also, in my 1994 article
Lambda, the Ultimate Political Party, I advance the hypothesis that languages are
defined as much by their community as by their semantics. That is, languages are forever
in flux, and the semantics you read about in a language spec is a point in a
multi-dimensional space telling you the current location, but it does not tell you the
velocity vector in that space. For that, you must look to the community. Even if two
languages happened to occupy precisely the same point in design space, that is, if they
had the same semantics, would they continue to over time? I think not.

For what it's worth, here are just some of the things I personally
like about ANSI Common Lisp:

Lisp is dynamic. The world is ever changing and it's useful to allow programs
to change dynamically with it. I can load new or changed functions, classes, and method
definitions into a running image that I'm debugging, or even in a deployed production
application. When I do, the code that was running will immediately start using the new
definitions. Classes can be redefined even if the new class has different slots, and, if
I care to, I can control how the update is done from old to new slot arrangements for
already-created instances. This kind of thing supports programs that must be continually
running yet must be responsive to changes or even just bug fixes.

Lisp is introspective. Not only can functions, packages, classes, methods be
dynamically added, redefined, or removed, but programs can also inquire about whether
aspects of the programming environment (functions, packages, classes, and so on) are
defined, can manipulate those objects as data, can save them away, can transform or
encapsulate them, etc. Also, the Lisp compiler is a standard part of the language and can
be invoked even at runtime by applications that need to augment themselves. New programs
can be created on the fly, then compiled and loaded and executed in the same running image
as they were created, without ever exiting (and even without doing file I/O). This
facilitates automatic programming and the development of layered languages.

Lisp's syntax is malleable. There's nothing worse than being stuck in a syntax that
you don't like in a language you're going to use for a long time. Lisp allows programmers
to reconfigure the syntax rules for parsing characters into data and programs, as well as
allowing macro technology that transforms one parsed program expression into another.
And it allows control of how data is displayed during program execution and debugging.
Moreover, this can generally be done in such a way that one programmer's customizations
don't adversely impact another's. This makes interactions with Lisp more pleasant and
debugging sessions more productive.

Lisp doesn't force users to use variable type declarations in order to just get
a program to run. The initial focus in Lisp is on getting programs working. You can add
type declarations when you're done if you want to, in order to enable additional compiler
optimizations. This facilitates rapid prototyping by first getting an application running
quickly with low overhead, and then allowing an application to be tuned as a second
pass operation.

Lisp has a powerful class system, and a flexible meta-class system. The class
system allows powerful slot and method definition, method combination, and a great many
other detailed features. The meta-class system allows users to treat the object system as
data that can be programmed, creating new kinds of classes.

Lisp gives the user powerful tools for both signaling and handling errors. This
means that when an error occurs, there are often a variety of ways to continue programs
other than simply aborting or dumping core. Moreover, object-oriented error handling
allows programs to represent errant situations, evaluate the options for how to proceed,
and select an appropriate option under program control.

Lisp uses automatic memory management. This means that when a programmer is
done with an object, they just let go of it and the garbage collector reliably frees its
storage. This means Lisp programs do not suffer from the memory leaks that commonly
plague programmers in many other languages.

7) What will it take to make Lisp fashionable again?
by kfogel

For myself and a number of friends, Lisp/Scheme programming has for too
long been a kind of mystical Eden, fading in our memories, from which we
have been mostly banished in our professional lives. But we can still
recall how it felt to work in a language able to shape itself to any
pattern our minds might ask: coding was more interesting and more
expressive, and the rate of increasing returns over time was tremendous,
because fine-grained -- almost continuous -- abstraction was in the nature
of the language. Life was just more fun, frankly.

Alas! In our jobs and even in our personal projects, we are often forced to use C, C++,
Java, Perl, or Python -- not because we prefer to write in those languages, but for two
much less satisfying reasons: first, everyone else knows those languages, so we'll get
more developers with them. And second, you can't count on users and testers having the
right environment to run programs written in Lisp/Scheme, so right away you take a
portability hit if you choose to develop in them.

Do you think there is a chance of Lisp/Scheme becoming "mainstream" again?
That is, when someone contemplates starting a project, it would be as
realistic for them to consider Lisp or Scheme as, say, Perl, without
worrying about losing developers or initial testers? What will it take?

KMP: First, let me say that I really appreciate the poetic description
you offer in the first paragraph above. I very much think that captures how I and others
think about the experience of using Lisp.

And as to the future of Lisp, I think the situation for Lisp is looking pretty upbeat
these days. Enough so that my own infant
business is building its tools in Lisp, both for sale and for our own internal use on
products we produce.

There are a lot of implementations,
both commercially maintained and "free", with a wide range of delivery options, from
conventional executables to "remote" solutions: Some implementations support CORBA and/or
COM interfaces, for example. Also, most implement some kind of sockets interface, and
there are several Lisp-based web servers available that build on this. Lisp programs can
dynamically load DLLs, or can be delivered as DLLs themselves. They can do "foreign
function call" to functions in other languages. It can also communicate with databases,
and so with other programs via databases.

As the world moves increasingly to high-bandwidth global connectivity, I think the
issue of the delivery environment will become less important. People have been waiting for
an e-Service based society to take off, and it hasn't quite done that yet, but I think
it's coming. I can't see how it won't. The overall savings in quality assurance and
support of not having to re-deploy an application in a hostile customer-premise
environment will be a lot, just as your question implies. One will just bring an
application up on the right kind of hardware, connect it to the net, and then forget about
where the program is actually being used. That may be an oversimplification today, but I
wouldn't waste my money betting against it for tomorrow.

8) Questions I've Come Across Learning Lisp
by Jon Howard

I was recently (April) hired-on as webmaster at Franz [franz.com], a
commercial lisp company (we make Allegro Common Lisp [franz.com]) which
has introduced me to lisp in a very loud way. Since joining these guys
(and gals), I've been thoroughly indoctrinated - with my full consent -
because of my belief that as computing hardware progresses programming in
more abstract languages will allow for more creative and effective use of
the platform. Sure, coding assembler on a new super-duper petaflop chip
will still be possible and less wasteful, but who would want to code a
million lines of asm to save a few (or even a few thousand) operations out
of a few billion, or trillion when it will only net a difference of
nanoseconds in the end? I'm less interested in making super-fast programs
than I am in making artistic and super-functional programs.

I'm not expressing the views of Franz, every member of the company has
their own beliefs on what makes for great programming - which is one of
the major reasons I find this place so fulfilling, everyone has complex
reasons for their design considerations, and everyone communicates them
(something I've grown to appreciate from working in too many places where
this was definitely not the case), and consequently I've been exposed to
quite a few different techniques of Lisp coding since my introduction half
a year ago. I'm constantly amazed that so many different styles of
programming can be expressed in the same language, it's capable of
accommodating any logical thought process that can be converted to code -
and I doubt many of you often use recursion in a logical way on a daily
basis, but even that can be done efficiently in lisp.

I'm still very new to lisp, and I was never a serious programmer in the
past, but I've always been accustomed to asking questions, and here are a
few that I'd like some input on:

If you learned any other programming language, did you initially find
the formalities of its structure to be a significant stumbling block to
understanding the language as a whole? Was the same true of learning lisp?

How much time do you spend debugging non-lisp code? How much on lisp?

What language took you the most time to learn - was it your first?

What feature do you consider to be the most important for an abstract
language to support efficiently - and which features have you found to be
most poorly implemented in lisp distributions?

I'd love to hear about what people think sucks about lisp and needs
improvement - or can't be improved, so far I haven't found anything that I
could complain about, the most difficult thing for me has been managing
all the documentation on a half-century old language in the process of
learning it. I've begun to love working in lisp, but I suppose being
surrounded by a group so full of passion for it has helped contribute to
my bias - if I'm wrong, help snap me out of it with a good argument
against using lisp. ;)

KMP: I knew FORTRAN and Basic before I learned Lisp. And I've dealt
with numerous languages of all kinds since learning Lisp. With most, the syntax itself is
generally not a burden. Some languages have more pleasant syntaxes than others, but the
human brain has an amazing ability to cope. Of all the many languages and syntaxes I've
seen, about the only thing I've never been able to cope with is the "*" used to
notate indirection in C. I understand thoroughly the notion of pointer indirection, and
the difference between "pointer to array" and "array of pointers", but I find it forever
hard to read and write that particular awful notation for some reason. Give me Teco or
Perl any day.

Mostly, though, I think the issue of how hard a syntax makes it to learn a language is
overblown. Humans have brains that are adapted to processing myriad special cases and can
mostly cope with obscure syntaxes. The real issue is how hard it is for humans to pass on
their knowledge to programs. People are good at judgment, and programs are good at
repetition. Over time, though, judgment tasks become repetitive and it's time for programs
to take them over. I like to write macros to package up things I do a lot, and the key to
that is having a reliable mapping between program syntax and program structure. The
last thing one wants is a macro language based on character syntax, since such
syntax is too unpredictable. Lisp offers macros based on program structure, and
that greatly reduces the number of programmer errors one makes in macro writing.

As to debugging, I try to use non-lisp code as little as possible because of how
hard it is to debug. Most other languages don't have good visual representations of their
data, so when I get in the debugger, the manner in which I am presented with errant data
is usually low-level and hard to read. A great deal of my valuable time is spent
painstakingly piecing structure back together. But in Lisp data objects have familiar
visual representations and I find it's usually easier to see what has gone wrong.

What language took me the most time to learn? Probably Teco. There was a lot of trivia
to learn there. What language took the least time? Probably FORTRAN, BASIC, Lisp,
HyperTalk, and MOO. Fortran just because it was small. The others because they are highly
interactive, which is a huge boon to learning.

Actually, I learned PostScript very fast, too. There are some excellent cookbooks on
this. But I never learned to debug PostScript. When my programs erred, I mostly just
wrote them anew and hoped they'd work then because debugging was too painful.

What do I consider it most important for an abstract language to support efficiently? My
time. Time is the only true, non-renewable commodity. I eschew languages like C because
they often waste enormous amounts of my time trying to develop and debug programs, and
justify it on the basis of micro-differences in speed that have just never ended up
mattering to me. I regard C as appropriate for use as an assembly language, but it
doesn't provide enough high-level services for me. When I'm old and grey and look back on
my life, I want to have done a lot of interesting things, not just have done a few
interesting things but "boy were they fast".

I think it's important to pick a language not on the basis of how fast its
implementations are today, but on the basis of how much they do what you want. Lisp has an
undeserved reputation for being slow, which I think results from deciding to make it do
things that there are not always known optimizations for at the outset. Like garbage
collection. But as Lisp is used, people complain about the things that are slow, and
fixes get found. So Lisp moves ahead. If Lisp had started instead only with the things it
knew how to implement efficiently, it would be holding things back. I want my ideas to
lead my technology and my tools, not to have my technology and tools leading my ideas.

9) Basis set for programming languages?
by PseudonymousCoward

As a Scheme and Common Lisp programmer, I got excited when I heard that
the Java Virtual Machine would have automatic memory allocation and
garbage collection. I thought it would be possible to build Lispish
languages to run on the JVM. The rate at which Kawa has been developed, to
implement a near-Scheme on the JVM has been frustrating to me. I attribute
this at least in part to the absence in the JVM of a construct equivalent
to Scheme's continuations. Do you think it is feasible to establish a
"basis set" of programming language concepts on which all programming
languages could be built, so that the distinctions between C, Scheme, etc
would be "merely" syntactic? If yes, please enumerate your candidate set.

KMP: Well, continuations are just functions. What's really lacking to
make this easier is good tail call support so that continuations can be called correctly
without pushing stack.

I don't really have personal experience with using the JVM directly, but my experience
with the MOO programming language led me to believe that there might be a problem with
integrating tail calling and security, since sometimes security is implemented by asking
"who called me?" and tail calls can mean that the apparent caller is not the real caller.
So I asked my spies at Sun about this.

I'm told that the original security model for Java worked the way I expected (by examining
the call chain), and that concern over consequent security matters contributed to the
absence of tail calling support in early releases. But apparently it was conceded a long
time ago that such support should be added some day, and that day simply hasn't come yet.
So perhaps there is hope.

Even so, I'm not so sure no matter how hard you try that you can just paper over the
many differences between languages and say that the only remaining issues are ones of
syntax. I do think you can probably get to a point where all languages can compile to
this machine, but that may not always mean that programs in one language are as efficient
as those in another, or that data structures in one language are as naturally represented
as those in another. For example, both Lisp and Scheme assume that small integers (that
would fit in a machine number) are still integers; they don't have the int/Integer
disjointness that Java has. A Lisp-to-JVM compiler could presumably hide this
distinction, but it would be wrong to say that the only difference between Java and Lisp
was syntax--there are really some material philosophical disagreements between the two
languages.

10) Scheme as an XML Translation Language
by Evangelion

I've become fairly interested lately in using Scheme (probably mzscheme) and the SXML
package as a way to do arbitrary XML translations in my free time (if I had any).

From the looks of it, the ability to create a reflexive mapping between an
arbitrary XML document and an interpretable programming language is too
powerful to be ignored.

Do you think that in the future one of the primary roles of Scheme/Lisp is
going to be in manipulation of XML documents, or is this going to be
relegated as an academic curiosity while the world struggles through
parsing XML in Java?

KMP: Are those my only two choices? The second one sounds awfully
bleak. I'd better choose the former.

I don't know whether you'll see XML as a formal part of either Lisp or Scheme any time
in the near future, but a lot of that is because the standards bodies administering these
are not extraordinarily active at this time. That doesn't mean the languages are dead,
just stable. Ongoing work is mostly happening at the level of libraries, and such
libraries can generally be written by anyone using existing primitives, without
modifications to the core language.

Lisp manipulation of XML and HTML is something people have been working on for a long
time. For example, the Document Style Semantics
and Specification Language (DSSSL) was a purely functional, side-effect free variant
of Scheme. Even XSL, the apparent replacement to DSSSL, offers the same kind of
functionality. It just uses a more CSS-like page model and XML syntax. But,
conceptually, it's Scheme inside.

In my recent professional life, I have personally written several XML parsers, all in
Lisp, for various employers and most recently for myself and my fledgling company. My
company's implementation is not available on the market yet, but when it is, I'm quite
sure the chief competition will not be around the availability of mere
"availability". Already there are a variety of libraries related to XML, XSL, and SAX
floating around. And I'm quite sure there will be more to come. Competition will be over
things like efficiency, robustness, representation, and optional
additional features.

11) Lisp vs. the world
by hjs

What do you see as the unique strengths and weaknesses of Lisp?

What strengths does it specifically have over other functional languages
(such as ML), over structured languages (such as C, Algol, etc), over
object oriented languages (such as C++, smalltalk, simula, etc), and over
scripting languages (such as TCL, perl, etc)? Can these other languages or
classes of languages be enhanced to include these strengths? If so, how,
and if not, why?

What about weaknesses? What do you see as the weaknesses of Lisp, both in
general and in comparison to the above classes of languages? Can these
weaknesses be eliminated? If so, how and if not, why?

I mean strengths and weaknesses not only in the formal sense of the
language itself, but also in terms of its usability in today's world. For
example, difficulty in delivering binaries or lack of accessibility of
system libraries from within common implementations of a language would be
considered weaknesses.

KMP: There are so many things I like about Lisp, but most of them
come under the heading of "doing things in the right order."

For example, type declarations in many languages are required but in Lisp they're
optional. I prefer to first get my program working, and only then to tune it to be more
efficient by adding type declarations. What's the point of doing a lot of make-work
declarations if you're not even sure you're going to keep the result? I do a lot of
exploratory programming just to answer "what if" questions. I also write lots of little
throwaway programs just to compute a simple result. I don't need such programs to run in
5 microseconds instead of 10.

I also view the process of programming as a series of "times" at which decisions can
be made: "coding time," "parsing time" (Lisp calls this "read time"), "macro expansion
time," "compilation time," "load time," and "execution time." Lisp gives me a great deal
more control for each piece of code as to when it runs, so that it can run at the
appropriate time when the data it depends on is known. Other languages, especially
statically typed ones, often make me specify information too soon, before it is really
known, which usually means "making up" answers instead of really knowing the answers.
Sometimes that makes programs run faster. Sometimes it just makes them run wrong.

And I like Lisp's willingness to represent itself. People often explain this as its
ability to represent itself, but I think that's wrong. Most languages are
capable of representing themselves, but they simply don't have the will to. Lisp
programs are represented by lists and programmers are aware of that. It wouldn't matter
if it had been arrays. It does matter that it's program structure that is represented,
and not character syntax, but beyond that the choice is pretty arbitrary. It's not
important that the representation be the Right® choice. It's just important
that it be a common, agreed-upon choice so that there can be a rich community of
program-manipulating programs that "do trade" in this common representation.

I write a lot of macros because there are a lot of interesting things one can do with
macros in Lisp. In other languages, macro-writing is a process of manipulating strings
containing input syntax. That feels very unreliable and I've never liked that. Lisp's
willingness to represent its code in known data structures makes macro writing feel a lot
more reliable. And the presence of macros in Lisp generally means that the boring parts
of coding get removed, because repetitive patterns usually get captured by a macro and
hidden away, keeping the developer's attention on the "interesting parts", and making the
activity of programming itself both more fun and more efficient.

Could other languages borrow some of Lisp's strengths? Sure. And they do. Java,
Dylan, and I suspect even C++ have all borrowed ideas from Lisp. But that's ok. We'll
make more. And anyway, it's not a zero sum game. Everyone benefits when there's this
kind of cross-pollination, whether it's Lisp influencing other languages or vice versa.

Weaknesses of the language? Well, that's harder to say. I think the basic design is
quite strong. Sometimes you see an implementation that has put more energy into some
parts of the language than others, but usually that has created a market opportunity for
another, so overall we have our bases covered.

For example, you might find some implementations that have big "hello world" footprint
sizes compared to "hello world" in other languages. Some in the Lisp community, don't
think this matters much, because disk and RAM are getting ever cheaper. "Real"
applications (i.e., not "hello world," but something meaty) of 5-10 megabytes are
pretty commonplace these days. Years ago, Lisp used to be seen as large, but due to such
criticism, Lisp has held its size constant in the last decade while other languages and
systems have bloated rapidly. So nowadays, Lisp is comparatively quite small. And even
still, if you don't like the size you get from one vendor, it seems there's always another
trying to squeeze into the niche of addressing your need. Corman Common Lisp (an up-and-coming commercial
implementation) and CLISP (a GPL-style "free"
implementation) have given special attention to this issue. So there's a vendor for
everyone on the size issue. And, though I deal more often in Common Lisp in my day-to-day
work these days, I would be remiss if I didn't mention that image size is also a key
concern of the Scheme language community, so that's yet another way the size issue is
addressed for those who see it as critical.

Some might have heard that Lisp, being dynamic, doesn't make use of static type
information. This isn't quite right. In fact, the language doesn't require static type
analysis, it merely permits it. This gives a lot of leeway to each implementation to
address the specific needs of its own customer base. The CMU Common Lisp implementation has, for example,
addressed the issue of type analysis in great detail and offered a clear demonstration
that there are many exciting things that implementations of Common Lisp can do with type
declarations if they choose to.

Why don't all implementations optimize all of these aspects--footprint size,
static type analysis, etc.? The Common Lisp language is admittedly conceptually large and
correct, efficient compilation requires considerable time and cleverness to implement.
"Why not make the language smaller so it requires less work to implement?" is a query you
hear a lot from the outside, and even from members of the Scheme community. The answer
from the Common Lisp community amounts to this: Programs are written all the time, but
implementations are written much more rarely. What the implementation does not do is left
for the user. The more hard work the language does, the less hard work programs do. In
effect, the thesis of Common Lisp is that bigger languages make for smaller sentences in
the language. (To see that there is at least some intuitive basis for this, think about
how long a novel like Gone With the Wind is in English, then try to imagine whether
the same novel re-expressed in Esperanto would be longer or shorter.)

If a language offers only what a programmer could implement overnight, it gives its
programmers not much of a leg up on their final application. Many members of the Scheme
community boast that they have written a Scheme implementation, while many Common Lisp
programmers have not. Common Lisp is surely harder to implement, but the Common Lisp
community does not see as its primary purpose to put out legions of implementors,
each with their own easily-created implementation. The Common Lisp community has chosen to
be about commercial applications, and its designers have provided a "meaty chunk" of
useful power for programmers to use, with the promise that if programmers write their
programs to that standard, not only will those programs work well today, but as
implementations get better, those same programs will work even better tomorrow.

It's been a long time since I've encountered a LISP fanatic. I thought they were extinct.

I've written about 10,000 lines of LISP myself,
know John McCarthy (who finally retired last week)
and even used a Symbolics refrigerator at one point, but realistically, LISP is an idea whose time has passed.

Representing programs as S-expressions, incidentally, has one terrible cost - it's hostile to comments. Because there's no place to hang the comments, LISP code tends to be uncommented within the text of the code.

He has a good point, though, that while LISP used to be considered a big language, the other languages have bloated so much in the last decade that LISP now looks small.

I don't know what planet he's from but, in general, C does not take long to write. C has this wonderful capibility called functions, and if you do a lot of repetitive work, you can write a function to do that repetitive work. Or, for example, in C++ you can pass a class of C++ functions and data as an argument, making it so that modular applications can pass the same code and data to all available functions for immediate use..

IMHO, he's just biased to Lisp, and I'm just biased to C. But, outright saying that C programmers are a bunch of speed-freak-holier-than-thou losers, was going a little far..

Sorry to reply to my own post, but I forgot one of the best ways to be introduced to Lisp: Emacs. It probably came with your OS or has been ported to your OS at some point, it is based on Lisp (albeit one not as powerful as Common Lisp), and you can get both an introduction to Emacs Lisp and a reference manual direct from GNU's web site.

I would love to hear Kent Pittman compare Lisp with the growing interest in quasi-functional languages such as ML and especially OCaml.

These languages give up the s-expression syntax, and thus the powerful Lisp macro facility which people like Paul Graham believe to be critical to high-end Lisp programming.

What they offer in return is static type checking, which has saved me countless hours of bug hunting, and some wonderful mechanisms for abstraction and code clarification: sum types, modules, functors, and exceptions.

I used to do all my work in Lisp/Scheme. And occasionally I miss the simple clarity of the s-expression syntax and the macros. But these days I do everything in OCaml and have been amazed at the ease with which conceptual structures become code.

Long ago and far away, I programmed on an Xerox Lisp Machine (Dandelion) for several years and immensely enjoyed it, so my comments are intended to be friendly rather than hostile.

While weak typing and dynamic scoping are great for some things, it really trips up a lot of beginner programmers. An alternative Lisp that requires declarations might be very helpful for beginners. For strongly typed languages, compilers are a major help in debugging.

I would agree that other languages have become huge, I think the problem is that Lisp is a big and idiosyncratic language. Some things are in Lisp because of tradition. Some more things are in Lisp because they were grafted on top of the tradition. Then you have exceptions such as macros that violate the usual rules. It is true that Java is also huge, but each object in the API follows a very restricted syntax.

CLOS has all sorts of interesting things in it such as multiple inheritance and methods for combinations of objects. These are very nice once you have learned to use them, but there are lots of pitfalls, too.

I guess this means Lisp is a power tool for those who have learned how to use it. But it is difficult to learn, and unfortunately, a widely-used and widely-understood (more or less) language needs to appeal more to the lowest common denominator rather than only to those that get it.

The definstruction macro takes the opcode number, opcode name, a stack picture, and the body of the function. It then expands into code for a function that implements the opcode. In the case of addi, this function verifies that there are at least two items on the stack, and that they are both integers, throwing appropriate exceptions for each error case. It then generates code to pop these items off the stack into local variables and also declares the output variable, making sure not to double-declare if some of the same variables are used on both the input and output. It then generates the body of the function wrapped up in an exception handler that restores the stack to its initial state before calling the exception hook if it's a restartable exception, or just calls the exception hook directly if it's a resumable exception (yes, Lisp has resumable exceptions so you can clean up and keep going). The macro then generates code to push the result back on the stack, checking for overflow if needed, and (optionally, for debugging purposes) verifying that the result was indeed of the correct type.

Finally, it generates code to add the opcode to the jump-table that the vm interpreter uses, and also to the tables that the disassembler uses.

For something like addi maybe 30 lines of code are generated. For something like swap, it only generates about 4, because the macro is intelligent enough to realize that with no body and no typechecking it doesn't need the exception handlers etc.
This one macro is under 100 lines of lisp code, and will save 5000 to 10000 lines boring, repetitious, bug-prone code!

Emacs uses a quirky dialect of a rather ancient Lisp. If you want to
learn Common Lisp, you will need to get a Lisp environment. I
recommend CLISP [cons.org], due to its
extreme portability, simple installation procedure (./configure; make;
su; make install), and relatively friendly CLI when not used via an
editor interface (tab completion mainly).

I recommend using ILISP [sourceforge.net] with Emacs.
It integrates with most of the Lisp environments out there and
provides some neat features such as sending the new version of your
defun to Lisp, and a slightly buggy buffer-package-matching thingy.
Here's the Common Lisp devel stuff in my ~/.emacs:

Well, I would have put it here, except that even with all the text below, the Slashdot lameness filter cens0rizes me. Email me if you're curious and I'll send you a copy.

[Sorry about this, but it looks as if I'll have to change the character ratios a bit...] Four score and seven years ago our fathers brought forth on this
continent a new nation, conceived in liberty and dedicated to the
proposition that all men are created equal. Now we are engaged in
a great civil war, testing whether that nation or any nation so
conceived and so dedicated can long endure. We are met on a great
battlefield of that war. We have come to dedicate a portion of
that field as a final resting-place for those who here gave their
lives that that nation might live. It is altogether fitting and
proper that we should do this. But in a larger sense, we cannot
dedicate, we cannot consecrate, we cannot hallow this ground.
The brave men, living and dead who struggled here have consecrated
it far above our poor power to add or detract. The world will
little note nor long remember what we say here, but it can never
forget what they did here. It is for us the living rather to be
dedicated here to the unfinished work which they who fought here
have thus far so nobly advanced. It is rather for us to be here
dedicated to the great task remaining before us--that from these
honored dead we take increased devotion to that cause for which
they gave the last full measure of devotion--that we here highly
resolve that these dead shall not have died in vain, that this
nation under God shall have a new birth of freedom, and that
government of the people, by the people, for the people shall
not perish from the earth.

CHAPTER 1

It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly through the glass doors of Victory Mansions, though not quickly enough to prevent a swirl of gritty dust from entering along with him.

The hallway smelt of boiled cabbage and old rag mats. At one end of it a coloured poster, too large for indoor display, had been tacked to the wall. It depicted simply an enormous face, more than a metre wide: the face of a man of about forty-five, with a heavy black moustache and ruggedly handsome features. Winston made for the stairs. It was no use trying the lift. Even at the best of times it was seldom working, and at present the electric current was cut off during daylight hours. It was part of the economy drive in preparation for Hate Week. The flat was seven flights up, and Winston, who was thirty-nine and had a varicose ulcer above his right ankle, went slowly, resting several times on the way. On each landing, opposite the lift-shaft, the poster with the enormous face gazed from the wall. It was one of those pictures which are so contrived that the eyes follow you about when you move. BIG BROTHER IS WATCHING YOU, the caption beneath it ran.

Inside the flat a fruity voice was reading out a list of figures which had something to do with the production of pig-iron. The voice came from an oblong metal plaque like a dulled mirror which formed part of the surface of the right-hand wall. Winston turned a switch and the voice sank somewhat, though the words were still distinguishable. The instrument (the telescreen, it was called) could be dimmed, but there was no way of shutting it off completely. He moved over to the window: a smallish, frail figure, the meagreness of his body merely emphasized by the blue overalls which were the uniform of the party. His hair was very fair, his face naturally sanguine, his skin roughened by coarse soap and blunt razor blades and the cold of the winter that had just ended.

Outside, even through the shut window-pane, the world looked cold. Down in the street little eddies of wind were whirling dust and torn paper into spirals, and though the sun was shining and the sky a harsh blue, there seemed to be no colour in anything, except the posters that were plastered everywhere. The blackmoustachio'd face gazed down from every commanding corner. There was one on the house-front immediately opposite. BIG BROTHER IS WATCHING YOU, the caption said, while the dark eyes looked deep into Winston's own. Down at streetlevel another poster, torn at one corner, flapped fitfully in the wind, alternately covering and uncovering the single word INGSOC. In the far distance a helicopter skimmed down between the roofs, hovered for an instant like a bluebottle, and darted away again with a curving flight. It was the police patrol, snooping into people's windows. The patrols did not matter, however. Only the Thought Police mattered.

Behind Winston's back the voice from the telescreen was still babbling away about pig-iron and the overfulfilment of the Ninth Three-Year Plan. The telescreen received and transmitted simultaneously. Any sound that Winston made, above the level of a very low whisper, would be picked up by it, moreover, so long as he remained within the field of vision which the metal plaque commanded, he could be seen as well as heard. There was of course no way of knowing whether you were being watched at any given moment. How often, or on what system, the Thought Police plugged in on any individual wire was guesswork. It was even conceivable that they watched everybody all the time. But at any rate they could plug in your wire whenever they wanted to. You had to live -- did live, from habit that became instinct -- in the assumption that every sound you made was overheard, and, except in darkness, every movement scrutinized.

Winston kept his back turned to the telescreen. It was safer, though, as he well knew, even a back can be revealing. A kilometre away the Ministry of Truth, his place of work, towered vast and white above the grimy landscape. This, he thought with a sort of vague distaste -- this was London, chief city of Airstrip One, itself the third most populous of the provinces of Oceania. He tried to squeeze out some childhood memory that should tell him whether London had always been quite like this. Were there always these vistas of rotting nineteenth-century houses, their sides shored up with baulks of timber, their windows patched with cardboard and their roofs with corrugated iron, their crazy garden walls sagging in all directions? And the bombed sites where the plaster dust swirled in the air and the willow-herb straggled over the heaps of rubble; and the places where the bombs had cleared a larger patch and there had sprung up sordid colonies of wooden dwellings like chicken-houses? But it was no use, he could not remember: nothing remained of his childhood except a series of bright-lit tableaux occurring against no background and mostly unintelligible.

The Ministry of Truth -- Minitrue, in Newspeak* -- was startlingly different from any other object in sight. It was an enormous pyramidal structure of glittering white concrete, soaring up, terrace after terrace, 300 metres into the air. From where Winston stood it was just possible to read, picked out on its white face in elegant lettering, the three slogans of the Party:

Re: Lisp doesn't have a toolkit equivalent to Java 2D + Swing, and I seriously doubt it has anything equivalent to Java 3D, the Java Advanced Imaging API, or the Java Media Framework.

Long before Java was born, Lisp actually led the industry in high-quality 3d graphics long ago. Around the time of the gulf war, CNN and other major TV systems were doing their graphics rendering in Lisp. There was some bad business management that led to the demise of the company with that tool, but the technical tools had nothing wrong with them. (sigh)

Re: I'd like to see, for instance, a word processor written in Lisp.

MIT Lisp Machines were the first to run an Emacs-style editor based on Lisp, I think. Then MIT Multics, where it was conventional to use PL/1, deviated to prefer Lisp as its implementation language. Then Stallman rewrote Teco-based Emacs in Lisp. It's different than MS/Word out of preference and tradition, not becuase something in Lisp keeps it from doing what Word does. But it is a word processor.

Also, Lisps can call out to other programs by native function call, by RPC, by CORBA, by COM, by sockets, and probably (though I haven't recently checked because I don't do Java) by RMI. So we're not lacking for ways to integrate others' tools if we need them.

Re: I'm not insulting Lisp the language, but the fact is that its libraries are woefully inadequate compared to Java's.

The Lisp community was in a boom at the time AI became unpopular. Many siezed upon the opportunity to blame Lisp for AI not meeting everyone's expectations (as if had the work been done in C++, AI would be blossoming today). It's easy for something to become a scapegoat, just as the word "dot com" has become a scapegoat for many companies doing bad financial planning recently. Since that time, Lisp has labored under a bad reputation that I think was unfairly attached as part of a convenient blame game. Yet even though many have tried to kill Lisp, it won't go away mostly because it still has ideas to contribute and commercial problems it can solve that other languages can't. It is gradually building back up to the image it had before, I think, by embracing rather than fighting other technologies. I dare say that if we had as much money to throw around in our community as Sun had to throw around getting Java advertised and populated with libraries, our image would be as good. We're just working on less budget, and so the process of rebuilding trust can't happen overnight by sheer force of dollars.

i like Lisp, but at my startup we're still using C, and not for speed, or (lack of) ease of use/debugging. It's because C gives you a handle on the machine. The (lack of) system interfaces in Lisp is a big problem.

For instance (and this is why we didn't use Perl, cuz at the time (now?) it's threads were buggy) we need to be able to use threads.

Maybe this is because Unix is written in C, not Lisp, but i think the Lisp community needs a little less "people don't use Lisp because they are stupid/lazy/afraid of change/old/don't get it" and more "why aren't people _really_ using Lisp?"

Actually, back in the 70's sometime, Vaughan Pratt (then at MIT, I think since moved on to Stanford or some such) invented this thing called CGOL, which was an infix syntax for Lisp. (It didn't require special magic to do; Lisp's syntax is redefinable, to it just takes a normal user program and a little imagination to do this.) He also wrote some much-ignored but very interesting papers on how its parser worked that I don't have pointers to but that I remember learning a lot from.

The Pratt parser used a modified parse precedence thing where any operator could take back control of parsing if wanted to. It was very flexible and reprogrammable and I swear by that model of parsing even today, much preferring it to simple bnfs and that kind of thing. But as to reprogrammability, I pointed out to him once, decades back now, that I thought the ability to dynamically rearrange parse precedences wasn't the win it seemed like it should be, because it made people uncertain as to what would associativities would occur. He seemed to sadly agree with me and said, at least then (he may have changed his mind since), that he thought it was probably better for defining a language than for offering a redefined language--that probably a language should just have a fixed set of such operators and then be done because indeed it turned quickly to a tower of babel if you rearranged parse precedences programmatically like the language technically allowed.

The traditional Lisp notation avoids this tower of babel by just making every expression syntax-neutral. No system-defined function or macro gets special "operator" parsing status, so no user-defined function or macro complains "hey, how do I do that?". The result, as most Lisp users remark at one point or another in their life, is a much more egalitarian environment, where system macros and user macros blend naturally without one having more apparent status than the other.