Re: How Common Lisp sucks



Ron Garret wrote:
Two things to get out of the way at the outset:

1. Note that the title of this post is *HOW* CL sucks, not *WHY* it sucks. The difference is significant. Please take the time to understand it before you flame me.

The title "How some aspects of Common Lisp suck" would have been even more appropriate, especially considering your own final remarks.

I am writing this because of the debate surrounding Steve Yegge's recent blog entries on Lisp. It is unfortunate that he made so many technical mistakes in his posts because they distract people from the fact that underneath all the errors he is actually making a valid point, that being that CL has very significant problems that are barriers to its adoption. (Some people think this is a feature, that having a few obstacles to overcome keeps out the rif raf. I suppose this is a defensible position, but I don't subscribe to it.)

There must be a bottom line somewhere. I don't think you would want the authors of the entries in the Daily WTF as a target audience

I'm going to point out just three problems with CL. There are more. None of these are original observations.

1. CL lacks standardized support for many operations that are necessities in today's world (e.g. sockets, database connectivity, foreign functions). Moreover, it lacks any mechanism by which these features could be standardized.

It lacks any _sanctioned_ mechanism for standardization. There is certainly a mechanism for creating defacto standards.

It is claimed that there are portable libraries that work across implementations that provide de facto standards, e.g. UFFI, but these claims are false.

You probably don't mean what you say here. There are definitely portable libraries out there. Maybe not for foreign function interfaces (I can't judge this), but certainly for other things.

The Balkanization of the CL implementation space also has the consequence that one must choose between using implementation-specific features and thus limiting the potential audience for one's code to a niche within a niche, or writing to the least common denominator, which generally means writing an awful lot of #+ reader macros.

....or writing compatibility layers.

2. Even for the one thing that CL claims to be particularly good at -- as a platform for embedding domain-specific languages -- it has significant limits. To embed languages that differ from CL's semantics in certain ways requires significant effort. To cite but one example: I would like to embed a language that is very similar to Common Lisp, but which differs in how it handles global variable references (to use global lexical environments) and ((function-returning-a-function) arguments) syntax. The former can be done using symbol macros, but only if the top-level definitions precede their first use.

The same holds for global dynamic variables: If you use them before you have defined them, you are invoking undefined behavior. So there is no difference between global dynamic and global lexical variables here.

If you reference a global before defining it then you're screwed. The latter cannot be done at all within CL unless you write a full code walker. But adding this capability is utterly trivial within an implementation. In MCL it takes two lines of code. And if it were done it would result in strictly greater expressive power.

The difference between (funcall (some-expression)) and ((some-expression)) is not that of fundamentally different expressive power. You get an increase in expressiveness when you can avoid having to touch various places in your source code by using a single construct. The switch from (funcall (some-expression)) to ((some-expression)) is a strictly local change.

For example, the addition of call/cc would indeed be an increase in expressive power.

(Note that increased expressive power is not necessarily a good thing. Consider the "come from" statement in Intercal as a counter example, which also mean an increase in expressive power when added to Common Lisp.)

Furthermore, it is not even necessary to agree on the semantics of ((...) ...). One could simply add a new macro defining form (or even a global variable) to set a user-definable hook for transforming expressions whose CARs are lists that do not begin with LAMDBA. All that would need to be agreed upon is the name of this form. Furthermore, this would result in strictly greater expressive power. It would be strictly backwards-compatible. And It would serve the needs of a number of users who are not currently being served (e.g. those who prefer to do functional-style programming without having to type FUNCALL all the time.)

You would have to define a way to delimit the scope of the different possible hooks, otherwise it becomes a nightmare to try to mix and match different third-party libraries.

But despite the fact that this change is easy and only good could come of it, it does not happen because there is no process by which this change can be effected (which is, I believe, a direct consequence of the fact that the realities of CL politics are that CL is utterly resistant to all change, though I would dearly love to be proven wrong on that).

The change you propose is easy to make, but the consequences of it are not necessarily easy to deal with.

I don't have the impression that the CL community is resistant to change. See the various projects in various places that are quite healthy, as far as I can tell. (If I remember corretly, http://cl-user.net counts more than 600 entries.)

(Oh, and anyone who wishes to prove me wrong, please not that there is a big big difference between effecting change in CL and effecting change in an implementation of CL.)

Sure. But do note that the language constructs that are part of Common Lisp have been tried in other Lisp dialects before. I think that picking a single Common Lisp implementation and experimenting with language constructs there to see whether they pay off before proposing them as official features is the healthier approach.

3. Much of CL's core is badly designed. For example, consider NTH and ELT. The functionality of ELT is a strict superset of NTH, so why have NTH cluttering up the language? (To say nothing of the fact that the order of the arguments in these two functions are gratuitously reversed.) Why is the function that computes the difference of two sets called SET-DIFFERENCE, but the function that computes the intersection of two sets called simply INTERSECTION? And why do all of these functions operate on lists, not sets? It's because there are no sets in CL, which means that CL leads one to prematurely "optimize" sets as lists. (I put optimize in scare quotes because in fact this is rarely an optimization, especially when your sets get big, and most of the time you have to go back and rip out huge chunks of code to replace your lists with hash tables or binary trees.) I could go on and on.

These features exist all for backwards compatibility. They could at most be deprecated, otherwise you would break a lot of existing code. I am certain that this would do more harm than bring any benefits because the community is, I think, not large enough to rewrite the large amount of useful code that does exist.

It's trivial to define your own package with the name and argument conventions that you prefer. There is no need to force anyone else to use the same conventions.

Now, for those of you who wish to respond I ask you to keep in mind the following:

1. The details of my criticisms are mostly irrelevant. What matters is that CL is far from perfect, and that it has no mechanism for change. So don't bother picking a nit about one of my specific criticisms unless you wish to argue that CL is perfect and doesn't need to change.

These nits would have to be picked in case we had an official mechanism for change. So it's a good exercise to do this already, in order to be able to estimate whether the installation of an official mechanism would be worthwhile.

I think there are better examples than the ones you propose. See for example http://www.cliki.net/Proposed%20ANSI%20Revisions%20and%20Clarifications

2. I know a lot more about Lisp that Steve Yegge. I spent twenty years programming in Lisp for a living. I have authored some highly referenced papers on Lisp. I am far from the world's foremost expert, but I'm no newbie. If you think I'm wrong about a technical point you should think twice.

3. I do not hate Lisp. It is and has always been my favorite programming languages. My love for Lisp pretty much destroyed my career as a programmer. My motivation for criticising Lisp is not to convince people not to use it. It is to effect changes that I believe are necessary to get more people to use it. To quote Paul Graham, "It's not Lisp that sucks, it's Common Lisp that sucks." And actually, I would soften that somewhat: it's not Common Lisp that sucks, it's some parts of Common Lisp that suck. But make no mistake, some parts of Common Lisp really do suck, and unless they are fixed a lot of people -- myself included -- won't be able to use it even though they may want to really badly.

Maybe.


Pascal

--
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
.



Relevant Pages

  • Re: How Common Lisp sucks
    ... blog entries on Lisp. ... NTH cluttering up the language? ... Lisp that sucks, it's Common Lisp that sucks." ...
    (comp.lang.lisp)
  • How Common Lisp sucks
    ... blog entries on Lisp. ... To embed languages that differ from CL's semantics ... Lisp that sucks, it's Common Lisp that sucks." ...
    (comp.lang.lisp)
  • Re: How Common Lisp sucks
    ... blog entries on Lisp. ... To embed languages that differ from CL's semantics ... Lisp that sucks, ... A newbie to these systems might be as overwhelmed with the ...
    (comp.lang.lisp)
  • Re: How Common Lisp sucks
    ... Note that the title of this post is *HOW* CL sucks, ... The title "How some aspects of Common Lisp suck" would have been even more appropriate, especially considering your own final remarks. ... btw, I think LTk is a nice start on the GUI bit, because Tcl/Tk offers other platform-independent goodies and nothing about it is Lisp-implementation specific. ... how many app developers are bouncing from Lisp implementation to Lisp implementation? ...
    (comp.lang.lisp)
  • Re: Survey: Do you use the "2" in Lisp-2?
    ... Why You should Not Use The Jargon Lisp1 and Lisp2 ... Graham's On Lisp, I'm wondering what the advantages of a Lisp-2 ... For another example, consider today's PHP language. ... Now, the question is, why do Lisps before Common Lisp have this multi- ...
    (comp.lang.lisp)