Mar 10, 2010

Why Common Lisp Bothers Me

I've been thinking about a newer project recently (yes, it's that time again) and I was thinking it might be cool to try to do the project using Common Lisp, since I don't know the language all that well and I'd like to try and get to know it better. I've used it a bit in the interpreter, and I used Scheme a bit when I was in university for the principles of programming languages and AI classes, and I find that while the syntax is weird at first, the languages have that neat homoiconicity property that seems to boggle the mind the more I think about it.

What seems to be bothering me about these is not the languages themselves, but how they interact with the real world. The problem started when I wanted to create an executable. You know, those things that you can give to other people that they can actually use to run your program. It took me a while to find anything, and eventually I had to run over to #lisp to find out. Their IRC bot pointed me to a page (apparently lots of newbies to Lisp ask this same question) which told me that Lisp doesn't really use executables. Instead it uses an image (like Smalltalk) which you can dump to an "executable". Except that it isn't really a compiled executable, but a saved state of your REPL session - kinda like if you were working in IRB and decided to hibernate it and when you ran your "program" it would just fire you back into the IRB session with the option of executing a function on its way in.

This brings up another small problem that I had a while back when I was trying to do my code mutation stuff, however a problem I had back then was with finding out how to do things using the standard libraries. I guess I've been spoiled by newer languages like Ruby and Python where the standard libraries seem to come with a large amount of basic functions for string/array (well they were lists, it was Lisp after all) manipulation and it is really easy to figure out how to do that kind of stuff, but when I tried to do some of the same stuff using CL I think I spent more time hunting down docs than I did doing actual coding (in hindsight I probably should have just wrote the functions myself, probably would have saved time that way).

So while I'm sure Lisp is a great language to use for academic stuff or maybe even for a server-side app, I don't think I want to use it for a project that I might want to give to people someday. It seems like the language suffers horribly from neglect, and the people who learn it love it so much that they seem to ignore certain practical matters like this.

Anyway that's the end of my rant. Flame away.

UPDATE: A few Lisp people commented on the post on Hacker News, saying my complaints sum up to things like: "Because I'm used to something else." I'm sorry, but those people have completely missed the point of my argument. It has nothing to do with what I'm used to, it has something to do with what anybody who is not a geek is used to. I want to distribute my application, it either must be executable, or work in runtime platform. The only runtime platforms that are feasible for large scale deployment are either Java-based or browser-based. Otherwise your app is going nowhere, as people won't want to install a whole bunch of crap just to get your app working. That's the point of the argument, it has nothing to do with what I'm used to.
Unfortunately I've probably just wasted the last 5 minutes of my time, because programmers tend to completely blank on reason and logic when it comes to their favourite programming language.


stereolambda said...

You might want to give clojure a go. It is a new Lisp that is gaining some popularity these days. It targets the Java VM and supposedly interoperates with Java very well (i.e. you can call any Java library from clojure - possibly the other way around as well but not sure). Might solve all your problems :).

Alan said...

Hmm, just a couple of comments. First of all, don't think of a CL image as a "session", the way you might think of a shell history. The image is the entire contents of the CL process memory, not just a script that gets played back into an interpreter. When you start an out-of-the box CL REPL, you're also loading an image, a standard one, and any image that you create yourself stands on the same footing as that standard. When you fire up CL with your own image, it can contain your entire application, including additional libraries, configuration variables, and pre-computed data. And unlike a "session", changes that happen during the run of a CL process don't get saved back into the image file unless you specifically dump them, so your application will always start in a uniform state. The way I prepare final builds of my CL applications is to write my code in packages, then create a build script in CL that just loads those packages and additional ones with ASDF, pre-computes data, then saves the image and terminates. I run that script, and end up with an image that just contains the standard CL environment and my code. Depending on the CL implementation, it can be a separate file from the CL "executable", or a full-fledged executable in its own right, and some allow you to automatically fire up a start function of your own, rather than the REPL.

Another mistake that I see CL newbies (not you) make is to try to build CL programs as small, quickly terminating programs, like for CGI scipts. I find it more useful to think of CL as a little operating system of its own, running on top of the native OS. Those images can be pretty large, and they are really good for building long-running processes like web application servers, rather than short scripts.

You are right about the strings though. There are usually peculiar Lispy ways of doing the things we're used to in other languages, but I was always amazed that CL doesn't have a specialized sting concatenation function, or a floating-point number parser, other than the one you get by calling READ. Nowadays, CL has a pretty impressive array of external libraries that are loadable through ASDF, but those two things are conspicuously absent.

MCAndre said...

Stack Overflow's your man.

I apologize on behalf of other commenters who did not supply an answer to your open question. Thank goodness for SO; now I know how to compile executables, too.