User login

Lisp, too, is mainstream

We've all heard Greenspun's Tenth and only rule. It's often applied to non-Lisp programming languages as well as to larger applications. It prognosticates that, eventually, all languages will become Lisp. One assertion that follows from Greenspun's rule is that if all languages are going to turn into Lisp anyway, why not just start with Lisp? But judging from the available features in languages today, perhaps it is too late to "just start with Lisp". Inspired by a post that found its way to my trusty feed reader, I think it may already be too late.

Greenspun's Tenth rule, from the Wikipedia entry, reads as follows:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

The basic idea is simple: as a program grows in complexity, the developers need to start reigning in the resulting chaos. Automatic memory management is added. Functional utilities start to pile up. Pretty soon, they fire up a parser generator and add some DSL's and a prompt. Eventually, it's just a hacked together version of Lisp without the parentheses.

The same, it can be argued, happens with programming languages. At first, they can only do basic scripting language stuff. Then the intrepid programmers discover the utility of a map operation. Maybe they implement a debugger. Or they really need anonymous functions. And, like before, it's not-quite-Lisp.

When faced with the prospect of having to manage a buggy, home-built codebase when all of the features you will have to develop anyway are already well implemented in Lisp, it seems like a no-brainer what you'd choose.

And I think that for a long time, this was true. But is it still true? What do we have now? The big players in the field are Java, C#, and Python. You might add Javascript to that list, too, depending on how you count it.

All of those languages have managed memory. Most have a decent debugger and feature-laden development environments. They run on different platforms. Python has decent functional-style programming. C# has some cool language development tools. They've got all these features that Lisp had long ago. But three things have changed---they're not ad hoc. They're not informally specified. And they're not buggy. The only thing that's still true is the slow thing for some of them and they're still half.

So, really, I think that Lisp, or its brainchildren, are yes, mainstream. So long did I think that my obsessive desires would lead me away from the mainstream. No, they only bring me closer to Java. Or, put another way:

And you're right: we were not out to win over the Lisp programmers; we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp. Aren't you happy?

That quote is from Guy Steele. Halfway to Common Lisp? That seems awfully close to voluntarily following Greenspun's Tenth Rule. James Hague over at Programming in the 21st Century has a similar view on the matter. He says Functional Programming is Mainstream---and has been for a while. Other programming languages have half of Lisp---and more that Lisp doesn't have. Lisp, or its essence, is mainstream. And after bringing the fire of Lispy programming to the world of languages, it is forced to face the onslaughts of a growing amount of weenie-bashing for all of eternity.

Ok. Maybe that was melodramatic. My point is that it may be too late to start with Lisp so you don't have to reimplement all of its features. Because all of those new languages have already implemented them. At least what most people consider the important ones.

I imagine people will disagree with this view. People might say that although Java and C# have many of the features that made Lisp great, it doesn't have the essence that makes Lisp still the best choice for discriminating programmers. That essence might include meta-programming facilities, or first-class closures, or macros.

Macros let you subsume more code into less code. Macros let you write more functionality with fewer lines. Macros let you abstract away boilerplate into new syntax.

But the corporate manager will say: if everyone writes their own syntax, my programmers can't read each other's code. So instead of having to learn a language once, they will have to learn a new language each time they approach a program for the first time. And the value of macros is lessened.

Code as data lets you manipulate code at runtime. It means you can optimize it, count it, store it, send it somewhere, and more importantly, write it in itself. The possibilities are endless.

But the corporate manager again has an answer: Java is already written. Why would I want to rewrite it? I have a program to develop---and you're worried about optimization? Let the folks at Sun worry about that. We're not language developers!

And so do each of the features fall like dominoes. Either they hinder some unforeseen corporate best-practice, or they just aren't really as powerful in that environment as one would really hope their expressive purity would like.

Python really seemed to be playing out Greenspun's Tenth for a while. I mean, really. Cool functional programming features. Strong support for a list-like basic type. Functions as the primary means of abstraction. And people were talking about it. They still do. And there was a sparkle of hope that one day, all of the features of Lisp would make it into Python. And that day would come when people realized that those other features were great. The Pythonists just didn't know how useful those features were. They just never used them before.

Check out this story as witnessed by Kenny Tilton.

At ILC 2002 former Lisp giant now Python advocate Peter Norvig was for some reason allowed to give the keynote address like Martin Luther leading Easter Sunday mass at the Vatican and pitching Protestantism because in his talk Peter bravely repeated his claim that Python is a Lisp.

When he finished Peter took questions and to my surprise called first on the rumpled old guy who had wandered in just before the talk began and eased himself into a chair just across the aisle from me and a few rows up.

This guy had wild white hair and a scraggly white beard and looked hopelessly lost as if he had gotten separated from the tour group and wandered in mostly to rest his feet and just a little to see what we were all up to. My first thought was that he would be terribly disappointed by our bizarre topic and my second thought was that he would be about the right age, Stanford is just down the road, I think he is still at Stanford -- could it be?

"Yes, John?" Peter said.

I won't pretend to remember Lisp inventor John McCarthy's exact words which is odd because there were only about ten but he simply asked if Python could gracefully manipulate Python code as data.

"No, John, it can't," said Peter and nothing more, graciously assenting to the professor's critique, and McCarthy said no more though Peter waited a moment to see if he would and in the silence a thousand words were said.

I quote this somewhat long story here because it really shows the dynamic. One person claims that they're close enough to be called a Lisp. Another guy pointing out "but you don't have this feature". It's just perfect. Python seems to be following that solitary Tenth Rule.

But the bomb was dropped, folks! Python, in its newest incarnation, is breaking the Rule. After absorbing all sorts of functional goodness from the Lispy womb, Python is rejecting its uterine confines! The news that Python 3000 (its projected release date) will reject lambda (!), map, filter, and reduce shocked the Functional Programming World. They later recanted some of it. But it is a bold statement against the tyrannical rule of Greenspun.

And Peter Norvig? The author of Paradigms of Artificial Intelligence? He knows about those other features of Lisp. Trust me. He knows what he's missing. And he chose Python.

I guess my point, through all this meandering, is that other languages did borrow a lot from Lisp. About half of it. And now those features are out there, in the world. And in the meantime, while they were borrowing, they got some new features of their own. Features like giant user bases, gazilions of libraries, corporate support, standards bodies. So Lisp has half of the features of Python. Java and Python are far from my ideal language---but so is Common Lisp. The idea that I would have to implement so much of Lisp on my own is a little overblown these days. And speaking of reimplementation: How much of Python's standard library does a complex Lisp program reimplement? How much of Python would you have to reimplement before you regret choosing Common Lisp?

Comments

Python 3000

There is much confusion over this, and I still, to this day, cannot figure out why.

Attention all those who think that Python is abandoning functional programming!!

Python 3000 will not "reject" lambda, map, filter, and reduce. It NEVER was. Instead, the language was going to be *refactored*.

Enough of an uproar occured where lambda will stay in as-is.

However, map, filter, and reduce will either be replaced outright with list comprehensions (thank you Haskell -- what was that about dropping its functional roots again?) or will be moved off into another module which you have to import to use them. If my memory of the e-mail with Guido Van Rossum some time ago is correct, this module will be written as a C module, so there will be no performance hit.

Remember, Python 3000 is a refactoring, to clean up the language from its current mess. Feature for feature, it not only matches the current Python, but even *exceeds* it.

I would also like to point

I would also like to point out some very important issues with respect to C#, Java, and Python.

C# has precisely one implementation.

Java has precisely one useful implementation (there are others, but all come with sacrifices).

Python has precisely one implementation.

Lisp? Not so much.

I'll tell you what -- you make A Lisp implementation, note the singular, and rally a community around that one implementation, work hard at pushing it, make it portable across Linux, BSD, Windows, et. al., contribute sensible, orthogonal libraries to it, and provide a SINGLE source for downloads, documentation, an easy-to-use and easy-to-contribute module system (which I think rules out 90% of ANSI CL), easy and standardized Lisp-to-C foreign function interface, and reject elitism in the user community, accept that portability is a myth and embrace POSIX- and Windows-specific APIs where it makes sense to (true portability comes from factoring common code -- witness how Python deals with OS-specific stuff via is 'os' module), and I can guarantee you you'll have a fair modicum of success.

This is happening with Factor today; with increasing frequency, I see people whom I'd never expect to use a stack-based language enjoying Factor. In five years time, I fully expect Factor to have a larger userbase than Arc.

your point

Does C have precisely one implementation? Is it popular?

Pretty much yes

Depending on your choice of platform, pretty much yes.

For Windows, there is the Microsoft Visual Studio über-IDE that has a C compiler buried in all those gigabytes of cruft. It is used by over 99.9% of all Windows developers. Its market dominance makes next to impossible to market Windows development tools.

If you are talking about Mac, there is... GNU C. It is used by just about every Mac developer that uses Xcode (although they prefer Objective-C, with good reason). It comes free with OSX and is really good.

If you are talking about Linux... GNU C is there.

And so on. GNU C is available for just about every platform.

And all this also has a price. It's painful to write a C program that will run the same on Linux, Windows and Mac, much less "look right" on any of them. And I know wx helps a lot with this.

It's not about having one "universal" implementation, but rather an "obvious" one.

BTW, Python comes in many flavors - IronPython, Jython and the vanilla Python are readily available for you to chose.

icc is a separate popular

icc is a separate popular C/C++ implementation, available on multiple platforms.
It is especially used on IA64.

Really? I've never heard of

Really? I've never heard of it. I question your definition of "popular."

Intel's c compiler is popular

Intel's c compiler is popular whether you believe it or not.

and even though both C and

and even though both C and Python have multiple implementations, if one of them does something questionable, you can point to the standard (C/C++) or the canonical implementation (Python) to see what is right. And all the major players at least attempt to converge. Is the same true for Lisp?

Ahh, "canonical" is a far,

Ahh, "canonical" is a far, far better term ot use than "single". Thanks for the correction.

Properly standardized?

You mean canonical implementation is good, as in "crap, in order to be fully Python-compliant, we must correctly emulate all CPython's quirks" (see PyPy)

... or is it more along the lines of having a canonical (per definition) *specification*? "Let's have a look at what the ANSI Common Lisp specification [X3J13] says about the behaviour of feature Y when we implement it."

Canonical as a standard

"You mean canonical implementation is good, as in "crap, in order to be fully Python-compliant, we must correctly emulate all CPython's quirks" (see PyPy)"

Well... Yes. There are many quirky standards around, but having a quirky one is better than having none as it fragments the target you write your programs to. Also, if CPython is too quirky, one can always propose something like Python 3 (that removes several quirks).

Python over Lisp

Regarding your comment on Peter Norvig knowing what he's missing from Lisp and choosing Python:

I asked Peter couple of questions, during a 2007 Google conference, in search of his take on Python over Lisp; he made two points that stuck with me.

1. Algorithms were more important than programming language choice.
2. Python is simpler than Lisp for your average corporate developer.

Interesting

This is really interesting. I just wonder about one thing: What about all the algorithms in PAI that are not implementable in Python? Could you write the pattern matcher? Could you write the sexpression optimizer? Are those algorithms not important?

Maybe not if Google employs the man who controls the language. They can always ask Guido to implement a pattern matcher natively.

I enjoyed reading your

I enjoyed reading your excellent essay. Thank you!

generic functions

are another feature I wish Python would pull from half of Lisp.

I dont think Javascript

I dont think Javascript should be added. It is basically a browser-only language.
Lisp, Python, Ruby etc.. dont have this problem. So I claim Javascript is "not serious".

Wow, that shows great insight

If there were a browser implementation of C, would you call C "not serious"? Probably not, because there is a C standard, and you can write standalone applications in C, and we all love good tools for debugging. Download Mozilla Rhino (not the limited one in Java 6) and have a look around. I wrote a standalone web server in 100 lines of JavaScript that is executed from the command line as "java -jar js.jar server.js". There's also a debugger that is better than any python debugger I have found, documented at http://www.mozilla.org/rhino/debugger.html. If you don't like the JVM, you can also write standalone applications using Mozilla XULRunner.

JavaScript continues to be the most misunderstood language.

Will you settle for two implementations?

In response to Samuel, to me it looks like there's a convergence to two Lisps, PLT Scheme and SBCL. Either one has just about everything on his list.

Yes, to read this delights me

Yes, to read this delights me greatly.

Re: Will you settle for two implementations?

I would have to agree that in the Scheme world, PLT seems to be taking over as "the" implementation to beat and with good reason. However, I think that if PLT was the only Scheme implementation out there, I would not program in Scheme.

PLT supports multiple languages which is great for teaching, it's primary goal, but I feel that in general it makes using it much more complicated than it has to be. Also, their insistence that I use Dr. Scheme if I wanna do serious stuff with PLT makes my sad. (Yes, mzscheme exists and will get you pretty far, but won't get your graphics. mred will get you graphics, but you have to do a bit of work to get the stuff from mzscheme as well. They basically say, use Dr. Scheme.)

But the popular Practical

But the popular Practical Common Lisp book points people to "Lisp in a Box" which on Windows uses CLisp. Why don't they recommend Cusp instead?

norvig is bad lisp coder

judging by the code published by norvig for aima and paip, he is a rather poor common lisp coder; he makes style mistakes and misuses features. long time before he turned to python he coded in the way python dictates - good for toy programs and 100-lines long modules; not really appropriate for really complex thing

Any examples of the bad

Any examples of the bad style? It's interesting, as PAIP is considered one of the best books for doing symbolic computation.

Clojure

s-expressions + macros + über multimethods + built-in software transactional memory + top-notch immutable data structures + direct access to all Java libraries = Clojure FTW

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.