1. Why I like Lisp.
  2. What I dislike about Lisp.

What I don't like about Lisp

Introduction

This is a companion to my previous page, where I attempted to show off the wonder that is Lisp. Sadly, things are not all roses in LispLand. If you're a lisper, and you cannot take criticism calmly, I suggest you read no further which will cause undue strain upon your arteries. Rather, go re-read my previous Lisp article "Why I like Lisp" and bask in the warm glow you receive :-)

My main beef is not with the actual language, but with the various implementations of it which are mostly geared for environments which are no longer with us.

Reinventing UNIX

   "Those who don't understand UNIX
   are doomed to reinvent it, poorly"
         - Henry Spencer

As Microsoft found out, you can either be UNIX-friendly or you can be behind[1]. The lisp compilers and editors and interpreters and tools (etc) that I've found all work well on UNIX systems but in a rather grudging sort of way, as if they'd rather run on systems more worthy (for example, either CMUCL or SBCL needs an existing Common Lisp implementation in order to build. WTF? The only other language I know of that has this self-imposed limitation is C, and thats because it has spent the last 30 years getting updated and refined as a general purpose systems language: all systems that ship with developer tools ship with C. C is the lowest common denominator, and if someone wants to write code, their system wil probably have a C compiler hiding somewhere in the filesystem just waiting to be invoked).

In all fairness, they do run well on UNIX, and they all have emacs compatibility which is a must for any UNIX-friendly program. The problem is that they have no common way of interfacing with the host OS, or even have a set of POSIX compatible functions.

It is true that the standard does not specify that Common Lisp should provide some sort of interface to the host OS, but to keep things in perspective neither does the C standard and I've yet to encounter a hosted C implementation that interfaced to the host OS so poorly that the user was tempted to write wrappers for the interfacing functions.

Quite a few of the free implementations (CMUCL, sbcl, clisp) run on quite a few of the UNIXes out there, but they all have their own set of "OS functions", which means that that nifty little self-aware[2] network monitoring tool you've written and named Skynet will only run under a single lisp implementation.

Cross-platform development

The problem gets worse if the program that you are trying to write uses the network or needs a GUI. I know that neither is in the ANSI standard, but once again I must point out that I can use ANSI-C and gtk to target a large subset of computers on a GUI application project, or that I can use BSD sockets with a very simple wrapper[3] to target a number of different architectures or operating systems.

I cannot, at this moment, use ANSI-LISP + gtk (or wxWidgets) to target anything.

Nevermind, maybe we can just write a C module that will do what we want (say ... provide network access) and then link in our module with every lisp implementation we want to use and then (from within our code) our network calls will be portable as long as our C module is there, hmmmm?

Nope. Can't be done easily, as all the lisp implementations have different methods of calling foreign (i.e. C) functions, with some (like CLISP) needing you to run through a mostly complex process (well, complex for someone who is just trying to learn the language) which ends in you dumping a memory image while the majority of the source code is written so that function-calls have insane macros surrounding them and the source files end in .d. Hello? Where's the C source that I may modify - I don't know what all these "d" files are for? The document might say, but I just moved on to another implementation.

Other lisp implementations need an existing Common lisp installed and working before they can be built, so where exactly am I adding in my C module?

Price

If you do try to do cross-platform development on lisp, it is highly unlikely that you will get very far with any single lisp implementation[4] unless you are willing to pay quite a decent sum of money.

Let me explain: One of the cheaper Lisp implementations with a decent GUI (and OpenGL interface) that runs on Windows and various unix systems costs $1100 per user per target. What this means is that should I be wanting to write a program (in lisp using this lisp implementation) to give away for free I will shell out $1100 first for the license for a single target OS.

The lisp community insists that this is not a problem; the problem, if you search the comp.lang.lisp usenet archives on google, is that the user who won't pay that amount is too cheapskate to pay for something that they use in the line of their work and that will probably pay itself off in 10 hours (if you bill per hour).

However, here in sunny South Africa, where the average developer nets $1100 per month, that is an entire months worth of work. Now lets say you want to write applications that targets the three main user-bases: Windows, Apple OS X and Linux. Thats 3 months salary gone, right away. And it makes me feel like a shmuck if I write something that I want to give away for free, because I am essentially then paying people to take my software.

The "too cheapskate" response of the community may well apply to people working and earning in the USofA, or to the people working and earning in europe which has an even stronger currency, but us poor folk in developing Africa will just have to use something else. C + gtk or C + wxWidgets target almost every current (and 5 year old) computer that can possibly support a mouse-driven GUI. Even java won't be able to boast the same numbers. It gets even better (depending on your point of view) if you replace C above with C++.

Meeting my needs

Okay, now I've chosen Lisp for a small (because I'm still learning) project, and after evaluating various different implementations (CLISP, CMUCL, SBCL, LispWorks, gcl and ecl) I've settled on one of them (won't say which one, that would be telling :-).

Of course, it doesn't meet my needs to a T, but that doesn't bother me because I expect that the added benefits of solving my problem in lisp will offset any extension code that I may have to write (for the free-with-source-code implementations) to make the lisp implementation fit my needs.

I pick the lisp implementation that seems most C-friendly, and find out that it's not yet as ANSI-standard-complete as the others. So I search the site in the hope of locating a clue as to the ANSI-ness of the implementation with no luck (there's apparently a test-suite to test this implementation for ANSI-completeness, but I cannot determine if something big has ben left out or if something small has been left out).

No big deal, I run a few tests myself making sure that the ANSI stuff I need is in. No problem, the ANSI stuff I want is there. Now, since this is the most C friendly (actually, it ties for "most" with one of the other implementations), I send mail to the developers mailing list saying that I plan to be a future (still learning, still learning!) contributor if I can and can someone please tell me the rules for contributed code (what gets accepted for inclusion, what does not, etc) and where to start?

Well, that was 5 days ago, and I still haven't had anyone answer the mail on the mailing list. Perhaps they don't want newbies messing up their lovely neat system? Perhaps they feel that their code is in no condition to accept patches until they iron out a few more kinks? Or perhaps the little green men said that with Jupiter rising now is a bad time to answer clueless (as I am) newbies? I honestly don't know.

Hell, if you let a newbie who's willing contribute, you'll get tons of documentation that may help other, less patient newbies. Man, I bet that my LaTeX skills will come in pretty handy if I document my experiences when trying to figure out this implementation (which I will do anyway, as I'll need it in a few years, even if no one else will).

Doubtless, I'll figure it out myself ... eventually, 'cos the source is *sarcasm*only 135Meg. I may have to devote a few weekends to it, but I'll do it anyway, cos the language itself is worth it.

But it would be nice if my needs as a developer could be met. If your implementation cannot meet my needs, then at least tell me where to start to make it fit my needs, because I assure you, my needs are not unique in any way.

If you application cannot fit my needs, then at least help me when I attempt to make it fit my needs, because a project that is an implementation of a programming language is dead if it doesn't meet developers needs.

The rest of my system

Rather sadly, none of the lisp implementations (even some of the commercial ones) let me use the dynamic libraries (DLLs, .so, etc) available in a system in a natural manner. Few of them provide stubs to access the OpenGL subsystem shared libraries, few of them let me do a query on which libraries are available and then load a certain library and locate a certain function within that library.

In C, or C++, or Perl, or Python, or etc ad nauseum I am provided stubs to the OpenGL shared libraries; Any C or C++ compiler lets me merely add the correct headers and let me statically link against their stubs (which will do the actual linking at runtime).

Unfortunately, lisp implementations tend to believe that lisp is the only language that is on your system, and that if it isn't available via lisp, then it isn't there.

As an example of this mentality within lisp developers, a few months ago I posted code to usenet that let me parse a file of name=value pairs like the following:

   default_location=c:\saved_files
asking for comments on my code. I was told by a few posters that I am doing too much work, just format the configuration files in a standard list which lisp will then read in and I won't have to parse. This really is easier in lisp terms.

Those posters obviously felt that my /etc/lilo.conf, and my /etc/services.conf, and most of the other config files in /etc would benefit from a new format that their programs (lilo, etc) would not be able to read unless changed.

Of course, in all fairness, they were not to know that I was trying to read in existing configuration files and not creating configuration files for my own application. On the other hand, even if I were writing my own application why on earth would I have the configuration files (edited by humans, remember) in a format that most humans won't consider intuitive and in a form that almost all systems administrators and users have never seen before. Everyone who's ever had to edit a configuration file has seen and understood the name=value files, who, outside of lisp developers has seen a list of name/value hash entries?

The perverse mentality of "Lisp: All or nothing" is hurting it, possibly more than anyone knows. I'm the type to rant and whine on my web-page about something (but then still bust my ass learning to make it work), but most developers will just move on. "Your system is the greatest of all time on Gods green earth? Why, sure it is ... bye"

Conclusion

What more can I say?

  1. The implementation treats my OS as a second-class citizen, and assumes that it runs on LispOS.
  2. The implementation works only on a small subset of machines I'd like to deploy on.
  3. The price to deploy on a larger subset of computers is astronomical for cross-platform free software developers (and pretty bloody high for the developing world).
  4. When your implementation does not do what I want, I cannot coerce it into doing what I want ("All the world's a LispMachine"?) and I cannot find sufficient documentation to help the lisp newbie to add his needs in.
  5. The implementation believes that there is no need for other programs on my system as long as I have lisp.
Obviously, I missed quite a few things in this article as I am a newbie to lisp. Possibly a few other things I mention are inaccurate or just plain wrong.

Well, then set the record straight and mail me about it (see the contact page for details.


Notes

[1]

For the last 10 years or more, the Microsoft marketing people sought to convince people that UNIX was ancient 30 year old technology, and that they (Microsoft) had a better method of doing things (for example, deriding command-line tools in favour of GUI administration tools). Vista brings with it more UNIX ways of doing things than any other Microsoft OS before it (including a rich command-line scripting environment). The irony is superb, and I suspect that Microsoft will probably catch up with UNIX technology-wise sometime in 2008 (After Vista gets a few service packs).

[2]

I kid, I kid :-)

[3]

I do, in fact, have such a library which, with the correct #define chosen in the build process (makefile), will target either BSD sockets or Winsock. It was not very difficult to write.

[4]

In all fairness, I expect that some of them will soon be quite far in their "support all computers, ever" effort; to my newbie mind it seems that Lisp itself is designed to be remarkably abstract, and if I am not wrong about the design, it does make me wonder why, with such abstraction, do the different implementations keep persisting on doing things in a manner few system administrators or normal developers are not used to. A prime example of "We do things our way, or hell freezes over" of lisp design seems to be the extremely unfriendly attitude of lisp implementations towards the C programming language, which is the lowest common denominator of HLL. If a language or language implementation cannot interface easily and readily to C libraries, its already dead in the water.