Postabon Blog

Tales from the Early Days 
« Back to blog

Why I chose Common Lisp over Python, Ruby, and Clojure

A few months ago, two co-founders (Stu Wall and John Buchanan) and I (Shaneal Manek) started working on a startup called Postabon.

The idea behind Postabon is simple: we wanted to create a platform where users could find and share ‘deals’ at brick and mortar stores (be they sales, coupons, happy hours, specials, etc). For example, if I’m out near a mall and need a pair of jeans I can pull out my phone and see which store near me is having the best sale on pants right now.

I just wanted to talk about a few of the high level technical decisions that I’ve made – in the hopes that it could help other people starting new projects out (and that I can get some feedback and learn something myself). This post is going to be pretty tightly focused on the language I chose. I have a few other posts in mind on topics such as the database (BerkelyDB) and overall architecture that I’m planning to write up in the next week or two..

Language

The way I saw it, was that as the sole programmer I needed a language that was concise, powerful, and that let me work quickly. This set of requirements, in my mind, eliminated Java (and I don’t know any C# …), which left me considering Python, Ruby, Clojure, and Common Lisp. I thought Haskell and Erlang were promising – but I’m just too inexperienced with them to commit to a large project (and, for better or worse, they aren’t really known as great languages for web applications).

Python

I am fairly experienced with Python, there are lots of great libraries/frameworks for anything I would want to do, and it would be easy to bring other programmers on-board later. However there were a few negatives that, in aggregate, were enough to get me to move on.

First, and most importantly, the Python 2 to 3 conversion really scared me. Most libraries I wanted to use were still Python 2 only – which meant I would have had to write Postabon’s back end in Python 2. But it makes no sense to me to write a large app, that I may have to maintain for years, in a language that has effectively received a death sentence. Python 2 is fine now – but in the coming months and years new libraries, features, and performance improvements are only going to be introduced in Python 3, and I didn’t want to get left behind or forced to take on an expensive and time consuming port in the future.

Second, I know it’s a bit cliche, but I don’t like the Global Interpreter Lock, which makes it basically impossible to write multi-threaded apps that work on multiple CPUs. Of course, writing a multi-process app would be a reasonable work-around, but it is a bit of an annoyance.

Finally, Guido’s disdain for functional programming makes it clear that I would be a second class citizen in Python-land. As a few small examples see:

My mind just works functionally, and I don’t want to be forced to fight the language I’m using at every turn.

Ruby

I’ve played with Ruby (mostly in the context of Rails) some – although I’m nowhere near as proficient with it as I am with Python, Lisp, etc. Ruby has a lot of the same strengths as Python, with fewer weaknesses. My criticisms about Python’s GIL apply to it too – but again simply using processes is an acceptable work-around.

The biggest reason I chose not to go this route is that the Ruby community is just moving too fast for me right now. Some major component of the development/production stack of choice seems to be changing every 6 months (e.g., I’ve seen the webserver go from FastCGI/Apache to Mongrel to Phusion to Unicorn). I couldn’t even easily figure out which version (1.8 or 1.9?) to use – or even which implementation (Ruby MRI, Ruby EE, JRuby, etc). Most of the articles I  found online are a few months old and I am told they are no longer accurate.

Also, much of the Ruby community is built around Rails, and I’m a bit wary of using ‘heavy weight’ frameworks like Rails (or Django) on large custom projects. In my experience they make the first 90% of what I’m trying to do be really easy – but then make the last 10% a living hell since I need to modify something the framework never intended me to control. I probably could have written a ‘bare-bones’ implementation of the site’s back-end in Rails in a week instead of two weeks, but I would rather ‘waste’ that one week up front to have more flexibility later.

For example, I ended up writing my own completely stateless session handling, building a fairly smart geo-spatial cache (in-memory R* trees that asynchronously persist to disk using B-Trees), and using a key-value store and raw b-trees for persistence (instead of a relational database). These (and a lot of other non-standard decisions I’ve made) are possible within Rails, but I think they would have cost me more time and energy than Rails would have saved up front – especially in light of my lack of experience with Rails.

In principle, I could see Ruby being the right choice for someone who was more experience with it upfront, is adequately plugged into the community and willing and able to switch out components of their stack. But, personally, I prefer a bit more stability in things.

Clojure

There are a lot of great things about Clojure: it runs on the JVM so I get all the Java libraries and that great JVM performance, it’s functional from the ground up, and it even has macros.

However, 6 months ago Clojure hadn’t even had it’s 1.0 release (and the language was constantly changing). When I tried to download it the Slime integration was completely broken and I had to manually search through the SVN repos of several key components to find a relatively recent working set of tools that worked together.

My feeling is that things are better now (Clojure is 2 years old!) and if I were making this decision again today, I would give much more serious consideration to Clojure.

Common Lisp

Finally, that brings me to Common Lisp. I have plenty of experience writing web apps in Lisp, so the high barrier to entry wasn’t a deterrent in my case. Although, make no mistake, that learning curve for writing a good CL web app is steep enough that I would warn most programmers to shy away from Lisp for writing a production app on a tight schedule (I would like to write a post or two that help new users get over the hump though).

I like that the language stabilized 15 years ago, that the kinks have been worked out, and that it has stood the test of time. I know the traditional complaint is the dearth of libraries, and there obviously aren’t as many options as they may be for other languages. While I have been fortunate to find several great options for everything I’ve needed to do so far (JSON/XML parsing, HTTP servers and clients, ORMs, etc) – more obscure libraries like Thrift and OpenID support may be an issue in the future. The lack of libraries is, without a doubt, the biggest disadvantage of CL and one of the reasons Clojure is so appealing to me. I can usually just write my own foreign function interface into a C library – but that’s really time consuming compared to downloading an egg/gem/jar.

The ability to use dynamic typing for most of my code but optionally give the compiler type-hints and get all the performance of a statically typed language for critical portions is a killer features that I still haven’t found elsewhere.

On balance, I think that Common Lisp was the best choice for me given my background and the needs of this project.

Status

Postabon just publicly released in New York! We are up to about 5K lines of Common Lisp (and well over 15K LoC total, including a website, mobile website, and iPhone App) and things have been progressing smoothly.

The next post I’ll write (probably in a few days) would cover our site’s general architecture. After that, I was planning to dig into some specifics about the best way to manage/deploy a production Common Lisp webapp, which I hope would help a new Lisper get off the ground.

Posted by Shaneal Manek 

Comments (62)

Dec 02, 2009
Steve Smith said...
Why did you rule out Java?
Dec 02, 2009
PauloC said...
One of the greatest problems I found when trying Common Lisp was the large number of implementations and the disorganization of the library space. It is hard for a newcomer to decide which libraries are available, which are maintained, which are dead. Would you care to mention which implementation and libraries you are using?
Dec 02, 2009
Shaneal Manek said...
I think Java is a great language - it's amazingly fast, runs everywhere, and everyone knows it (I've worked as a professional Java dev before).

But, in this case, Java's advantanges didn't really buy me anything. In particular:
-Raw CPU speed wasn't too big an issue - Disk I/O is our real bottleneck.
-I don't really care where it runs (or how easy it is to distribute) since I only need to run a handful of instances which I manage myself.
-I get to choose my own dev team, and I know dozens of great Lisp programmers who I would love to work with (so finding a 'common' language isn't too big a concern.

But it's disadvantages (verbosity, lots of boilerplate, no type inference, no TCO, etc) did hurt me.

Dec 02, 2009
Shaneal Manek said...
@PauloC: My next two posts focus on exactly that. The big libraries I'm using include Hunchentoot as my webserver, Elephant for persistence (although, CLSQL is great too), html-template for generating HTML (although, CL-WHO is nice - particularly when paired with parenscript).

I'll write much more about it in the next week or two though.

Dec 02, 2009
Brian said...
Your understanding of the state of Python is myopic.
Dec 02, 2009
Shaneal Manek said...
@Brian: How so?

I know Python 2 is still active now (and going to maintained forever ...) - but I don't think it's unreasonable to expect a lot of new/cool features and libraries are going to be Python 3 only within a few years.

Dec 02, 2009
Paul Gordon said...
As a C# developer looking at branching into pastures new, this is a great article. Thanks!
Dec 02, 2009
synchromesh said...
Hey, this sounds great! (Particularly because I agree with your conclusions. ;)) I'd be interested to know whether the ease of doing DSL-type stuff (or macrology in general) is a factor for you (including things like ParenScript).

Anyway, I'm looking forward to more posts on this topic. Now, where's the RSS feed...

Dec 02, 2009
kunjaan said...
I was wondering if you gave any Scheme implementations any thought?
Dec 02, 2009
paulrpotts said...
Well said, especially your comments on Python and functional programming. It's my biggest barrier to really enjoying Python now, not to mention using it for several projects. The folks in my team who are using Python are using it in an excessively object-oriented way, which means huge objects that are really managers, which is a design anti-pattern, and very long methods that with a little rethinking could quickly become very short functions. (When all you have are objects, everything looks like -- another object!)

I've created a proof-of-concept that shrinks some of that code by a factor of twenty, dramatically reducing copy-and-paste programming, but I felt that I was fighting the language, and got the feeling that this functional style wasn't really wanted. In particular, I want lambda, map, reduce, curry, and zip, and I don't want them to be buried in a library, or considered second-class, or broken. Comprehensions are nice, and I can live with that, but your comment about Python's closures is well-taken.

You can find more detail in my blog post here:

http://praisecurseandrecurse.blogspot.com/2008/02/is-python-acceptable-haskell.html

Brian, why do you think the author's understanding is "myopic?" Because when I tried to embrace Python, I came to similar conclusions. It seems to me that with my background extending from Pascal, C, C++, Dylan, NewtonScript, Scheme, Java, and many others, my vision is anything but, even if my eyesight isn't very good!

Dec 02, 2009
Shaneal Manek said...
@synchromesh: Thanks. Macros are great (I have a whole bunch internally helping me to define pages) and I even built a small human readable DSL to represent a recurring event.

But, to be perfectly honest, it's really hard (for me at least) to write hygienic macros in Lisp. Maybe I just need more practice, but I often find subtle problems in my macros upon more thorough inspection (and they usually crop up 6 months after I wrote the code ;-)). So, I usually try to avoid them in favor of functions/methods when I can (although, sometimes you just need a macro ;-)). I think this is one of the things Scheme does really well ...

Dec 02, 2009
paulrpotts said...
(And, speaking of Haskell, not to criticize in the slightest, but if I were looking into getting a startup going with a new programming project, I'd definitely be attempting an implementation in Haskell, at least as an experiment).
Dec 02, 2009
Duncan said...
I know it's not mentioned, but did you consider Lua at all? It sounds like it would have been quite close to what you want, even if CL might still have won out over it in the end since you clearly already knew it very well anyway.
Dec 02, 2009
Shaneal Manek said...
@paulrpotts: Feel free to criticize ;-) I agree that Haskell seems really great. Unfortunately, my experience with it is limited to a single reading of Real World Haskell, and I don't think I know it well enough to undertake a real project until I've at least done a few side projects first.

@Duncan: To be honest, I don't know much about Lua (except that a smart friend of mine loves it). It seems very interesting (and relatively easy to learn compared to, say, Haskell). I'll be sure to keep it in mind for future use.

Dec 02, 2009
Ingo Hoffmann said...
What about Groovy?
Dec 02, 2009
rubbishbucket said...
I think that your reasons for choosing Lisp has nothing to do with the shortcomings of the other languages or platforms but simply that you know Lisp well and shaped your arguments to reflect that. And hence, you chose Lisp by begging the question.

Lisp is a fine language but any framework Rails, Spring, Grails, Lite, roll-your-own MVC, etc. in any modern language would almost always be the correct engineering decision.

The state of functional languages have come a long way since Lisp, e.g.: SML, Ocaml, Haskell, Erlang, etc. If you're going to choose Lisp anyways, any one of the those languages would have been a fun candidate for your site. The best way to learn a language deeply is to start using it. And Postabon seems like a simple enough site for such experimentation.

Dec 02, 2009
Volkan YAZICI said...
What do you think about the lack of a standard threading(!) and networking(!) support in Common Lisp? Did you see the platform specific hacks usocket and bordeaux-threads (which are the backbones of your Elephant and Hunchentoot) do to cope with these restrictions? (BTW, the last time -- a couple of months ago -- I checked usocket, it was still lacking of a portable WAIT-FOR-INPUT functionality. Similarly, bordeaux-threads was suffering from JOIN-THREAD.) Isn't it a problem for you that you won't get a stable and high-performance API for threading (do not even talking about coroutines) and networking stuff in CL standard for the -- with your words -- next fifty years, considering the inevitable reality of communication (networking, etc.) and concurrency problems?

If I understand you right, in case of success, you wish to keep up with this design and tools. Would you mind eloborating about your scalability plans? Will CL still be a sane choice in such a case too?

Dec 02, 2009
piyush said...
Ruby: You should have looked at Jruby more closely. Jruby doesn't(yes) have a GIL and it is going to be the only implementation to have that 'feature' for a long time. Moreover, I think Rails IS a bloated framework but you need not stick to it. You could have used sinatra or merb which are very lightweight and modular respectively.

Lisp: I think lisp sucks at: 1. Talking to a regular DB, 2. Good and mature libraries, 3. Good templating language. If your app doesn't use a RDBMS and you are not going to use any major third party, CL can work really well. It is a very robust system.

Dec 02, 2009
 said...
Hey Shaneal,

wow is pretty impressed that you're using lisp for your web startup, i know reddit once was in common lisp. I have no experience at all with functional programming, i do mostly OOP, i want to ask you why you didn't consider scala or why you didn't choose it, it has it's own web freamework lift.

I want to start learning a functional programming language, i do not know which one yet, but i guess it should be scala or clojure, what would you say?

cheers.

Dec 02, 2009
J said...
You are right about CL libs it's a dismal state of affairs. I know you can get pretty far with open source CL projects like SBCL, Elephant, etc., but if you are truly going down the CL path for sure, I *strongly* recommend investing in a commercial implementation. I have used them all (well, both of them ;-) ) and for what you want to do I recommend Allegro CL. It comes with tons of libraries including a web app framework called WebActions, also a b-tree database so you can ditch Berkeley DB. Over all the environment feels "fully baked", unlike the hodgepodge of open source tools in the CL world.

Please note I'm not affiliated with Franz. I've used their tools and they are quite good IMO, and I'm simply making a recommendation to invest $$ in tools. Support is also good. I know you think they are expensive but it's no more than an MSDN subscription. Download the free version and evaluate it.

Dec 02, 2009
Shaneal Manek said...
J: I've played with Allegro and think it's great. But their licensing is insane. I have to pay them per-user of my website. (http://www.franz.com/products/licensing/commercial.lhtml)

If they told me "Pay us $3K and you're good to go" (or even better "use us for free until you have revenue, then pay us $3K") I would use them. Microsoft lets me use anything they have for free, until I have good revenue through their BizSpark program, for example.

But paying them per user on a (free) website is crazy.

Dec 02, 2009
Shaneal Manek said...
J: Posterous broke my link. Correct Link: http://www.franz.com/products/licensing/commercial.lhtml
Dec 02, 2009
Tom said...
One thing about python that you either don't know or are being dishonest about:

Removing map() and filter() doesn't really matter.

Map is just [f(x) for x in inpulist]

Filter is just [x for x in inputlist if pred(x)]

Reduce should stay IMHO, however.

Dec 02, 2009
Troy Millington said...
Congratulations on your launch. This is a great concept and I am excited to see a functional language deployed for this functionality. Looking to your future posts on your experiences and suggestions for other implementors (partial to Scheme conceptually myself).
Dec 02, 2009
Shaneal Manek said...
Tom: I am aware of that. I don't really care that map/filter would be removed - I'm more worried about the mindset you would have to advocate doing so. I was just using that of proof that the Python community isn't very functional-friendly. Guido has said on many occasions he doesn't really like a functional programming style.

It's just a stylistic difference, but I happen to like functional programming and would prefer to work in an environment that encourages it.

Dec 02, 2009
Marc Hildmann said...
Great to read about a cool startup using lisp! I'm looking forward to read Your next posts.

What I dislike about ruby (on rails) is the deployment.

I'm using newLISP for about six months now and developed a web framework called Dragonfly. May some guys from here have a look at it.

Dec 02, 2009
ctherien said...
I had the same dilemma last spring. I hesitated between Clojure and Common Lisp and I hesitated and I hesitated without end. Finally I decided to go with Clojure. Well the good idea, tools are very stable (slime), the version 1.0.0 is very stable, great stuff now. Some libraries are so so but you can't get all and you have java any-way. Improvement to ABCL is going at speed light these times, something to look at.
Dec 02, 2009
Vince said...
I would make my language decisions based exclusively on hiring. If you're planning on being a one man shop, you can use whatever language you like, but otherwise you can't ignore the fact that a) people want to put something on their resume that will help them get their next job and b) hot young talent will be chasing the latest technology fad.

Maybe my finger is way off the pulse of the modern developer, but I'm pretty sure choosing Lisp is going to severely limit your talent pool when it comes time to hire.

Dec 02, 2009
Brit Butler said...
@Volkan YAZICI: Can you elaborate on what the platform-specific hacks are in usocket or bordeaux-threads that would impair stability or scalability? I'm not familiar with them.

Can anyone else speak to this?

Dec 02, 2009
Shaneal Manek said...
@Vince: I know plenty of great Lisp devs who I would love to hire if I had the resources and need. ITA Software (for example) seems to have no trouble finding them. Lisp is also pretty easy to pick up - and I'm not opposed to teaching them on the job (if I ever exhaust the dozen or two Lisp programmers in my personal network ;-)).

Personally, I would love to work at a company that used a cool, but somewhat esoteric, language like Erlang, Haskell, OCaml, Clojure, etc. In my experience, firms that use these sort of languages tend to be very tech savvy (i.e., have smart people that I can learn from) and are fun places to work.

Dec 02, 2009
Robert said...
"they aren’t really known as great languages for web applications"

I don't classify CLOS as that either.

Dec 02, 2009
Joel Reymont said...
Actually, Franz does let you use the software free until you start making money. You just have to ask. Ask me how I know ;-).
Dec 02, 2009
Shaneal Manek said...
@Joel Reymont: Thanks that's good to know (I wish they advertised that ...). Mind if I ask how you know (sounds like an interesting story ...).

But I still have to pay them per user of my (free) website at some point, right? And that's the real deal breaker. I wouldn't mind a fixed cost - but for a free website per user fees don't really make sense.

Dec 02, 2009
Chad said...
I think down deep you just want to write the project in lisp because it's cool, different, and challenging.
Dec 02, 2009
bubo said...
good choice! hack the good hack!
Dec 02, 2009
Richard said...
@Shaneal: Franz is pretty flexible about licensing arrangements; the per-user licensing model is intended for delivered shrink-wrapped software (remember, they've been selling CL for twenty years), and pretty obviously doesn't apply in this case.
Dec 02, 2009
Thomas M. Hermann said...
So, you bought a new car?

http://groups.google.com/group/comp.lang.lisp/msg/a5d5c10f811b81e8

Dec 02, 2009
 said...
Great project! Take the REPL brother, and may it serve you well.

I knew very little Common Lisp a year ago, but I've been working on some side projects in that language and I like it a lot. My favorite thing about Common Lisp is that it feels like it places no restrictions whatsoever on the programmer, something I can't say for any other language I've used so far (all the well-known ones). Such liberalism could be a bad thing, I suppose, if you were a lead programmer trying to enforce certain coding standards. But for me and my side projects, the freedom of expression translates into pure bliss. And succinct, readable code. The only bad thing about Common Lisp is that now that I'm getting used to some of the features, working with most other languages is a little less fun.

Dec 02, 2009
David Brady said...
An excellent and well-reasoned post, thank you! I agree slightly with rubbishbucket that you seem to have picked the language that you are most effective at wielding; however I think this is a feature of your reasoning, not a defect. Imagine! Choosing the most effective tool at your disposal!

If you are planning to hire a developer and hand this project off to them, you may not have adequately counted the cost of having a lingua franca, but if you have no immediate plans in that direction then most of your arguments fit well.

If I were to do a project similar to yours I would probably use exactly the same criteria and arrive at Rails. This is because Ruby is my go-to language and the difficulty for me to write a clean spatial abstraction in Rails is probably comparable to the difficulty for you of writing it from scratch.

To get there, I got past the same kind of learning curve you had to pass with CL web development. I am *VERY* interested in your tips for getting past that learning curve; if you get time PLEASE write those posts!

Dec 02, 2009
alleagra said...
' it's disadvantages '

" it's " always, without exception, means " it is ". But doubtless you know that already.

Dec 02, 2009
quasi said...
:)
Congrats on taking the plunge with CL for your startup. I know there are huge negatives which people claim talk about. But the pure fun of working with Lisp cannot be beat. The productivity is great. It's not at all difficult to learn if you get the right introduction (because it's a different way of doing things). We had 4-5 absolute newbies with no major programming background trained and doing fine with CL in a couple of months.

The library quality does not suk per say. The few libraries which are most essential work very fine. The breadth is lacking and can be quite a pain for quickly delivering stuff.

The biggest advantage according to me is the ability of designing solutions without worrying too much about the implementation of those as opposed to fitting your problems to existing solutions. This is critical for larger applications. But this also needs more experience from the part of the designer so as not to screw up. :)

Stability and performance of the platform are very positive. We have had systems up for months without looking at them again.

Many of the problems of designing high performance systems are solved by architectecting appropriate solutions and not necessarily by the use of any specific platform. People hate php, yet flickr runs on it.

The inherent stability of a well tested functional code base shows dividends in the longer run.

The community is very helpful if you are not too anal (as with most communities). :)

best luck

Dec 03, 2009
quasi said...
One more thing : I would suggest you _talk_ to franz directly and see where it goes. Allegro is quite kickass. (not to take anything away from SBCL or CMUCL both of which are also kickkickkickass)
Dec 03, 2009
TheDarkTrumpet said...
I like your comments a bit about this. Some of the responses were right on the money, others a little..well, not so much.

For mature libraries, there are plenty of them out there. CLSQL, LML2, CL-PPCRE are the main ones that come to mind as available options to write up a web site fairly easy. CLSQL is database agnostic, so you're not stuck to one implementation - heck, I'm using CLSQL to access a MS SQL Server 2008 database through ODBC. LML and LML2 are developed by b9 as well, and give a more lispy-syntax for your web source code. CL-PPCRE well, regular expressions - I'll leave it as that.

To the author: I had a few questions on how you're doing with the site - the libraries used, but most of all:
- Have you found a solution for some of the full-stack testing, especially automated? It's been something I've been toying around with trying to write up for CL since there's not very many test frameworks, especially full-stack testing.
- If you develop web service APIs (rest or soap), could you pretty please abstract out the library and publish it open source :)? I had a fairly huge battle recently trying to find an acceptable SOAP solution for CL - which drove me nuts and had to give up and fall back to Python for SOAP testing.
- Actually, more accurately with the above, any custom libraries you build that aren't in the community, could you publish (ones that aren't business secrets, just thinking of ways of increasing the library support for CL).

I'm glad to hear you're doing the site in CL though. I am redoing mine over the next few months in CL as well, hopefully touching on some of the issues described here in regard to library support.

Dec 03, 2009
 said...
Congratulations, a great choice. We have also been using CL and elephant for a startup which I won't advertise because we are soon releasing an improved version. I had the same experience with Franz. And for a setup with several processes talking to the same db acache had some issues. It might be solved by now, when I pointed it out they were really eager to fix it, so their support seems great. Anyway, for the case when you want to have several servers talking to a common object database I can recommend our postmodern backend of elephant. We have been running it for 12 months+ and optimized it and sorted out some issues on the way. Not with much load but anyway.

I don't know if I lack imagination, but I am curious what libraries people miss in CL. Soap? There is CL-SOAP which I have never tried. We use json-rpc instead. Full-stack testing? I am not familiar with the term, when googling I found a link to Selenium+Rails but there has been a CL driver for selenium for several years. I am planning to do a buildbot like thing in CL, if that will be of any use, but that is not really a library.

Answers to plysch: 1. Talking to a regular DB: CLSQL, Postmodern and more.
2. Good and mature libraries: I am sure you can find some good and mature Lisp libraries. The embedded prolog compiler I am coding with today is 17 years old. Rethoric question: Is that more mature than any of the good open-source embedded prolog compiler libraries available for JRuby, Python or Java?
Also there is a mature test-framework RT that is 19 years old, older than the Java language, but I prefer FiveAM which is only five years. Now I could ask how mature the ruby frameworks merb and sinatra you mention are, but I will look it up myself. I love the sinatra homepage, worth a special journey.
3. Good templating language: HTML-template and TAL, but for us it is more common to generate markup from an embedded lisp syntax instead of using template languages.

Dec 03, 2009
ieslick said...
I got carried away here, but try to address a number of earlier comments.

By way of background, my coding experience was primarily in C, C++, and Java although I did teach Scheme for a bit in the early 90s. I was mostly an embedded systems architect/developer. I switched to Lisp in 2004 after a decade of lobbying by various Cambridge colleagues.

Perhaps it was simply the marked contrast to Java, but I found that I could finish projects in lisp faster than I got bored with them. In Java I had exactly the opposite experience. It took so long simply to express concepts in the language, that I would timeout before I finished a project. Since '04 I've written 10's of thousands of lines of code in Common Lisp.

My recent experience is relevant to this post as I made the switch from Python/Django to lisp for my first website project (http://www.lamsight.org/).

For reference and context, my core website stack is: ClozureCL / Hunchentoot / Elephant / Weblocks / Montezuma (full text search). I run this stack on OSX for development and Debian for deployment. Migration between the OS platforms is seamless.

I make direct use of (at least) the libraries: bordeaux-threads, drakma, cl-ppcre, cl-l10n, langutils, cl-markdown, ironclad, cl-twitter, f-underscore, anaphora, arnesi, and my home-grown stdutils.

I make heavy use of emacs, slime, tramp, and ssh tunnels to do interactive remote diagnosis and hot-patching. http://bc.tech.coop/blog/051227.html

The primary reason for switching from Python was the 90/10 problem with large frameworks described earlier. I found that I made fast progress when I was working within the vision of the framework supported, but then found myself fighting it to do something I needed that it didn't support (I need highly dynamic and user-extensible data schemas for LAMsight, thus my interest in Elephant).

While I liked Python just fine, but there are two big things I really missed from Lisp which became particularly useful for website development once I switched back.

1) Interactivity - what I like best about Lisp is the environment (Emacs, SLIME, lisp runtime) which are tightly integrated with the language's dynamic capabilities. The ability to interactively manipulate stack behavior (signal, handle, restart), to edit and inspect stack frames, and to incrementally update running code is invaluable. Paul Grahams 'Beating the Averages' captures the essence of this nicely. You can do this in other languages, but I've never seen it work so smoothly.

2) Macros - I found myself doing a fair bit of repetitive typing in Python where there wasn't a good functional abstraction of an unusual control structure. This is an annoyance, but I like being able to have the function names and s-expression structure clearly capture the idea of the function. I also use a variety of small DSLs or custom data formats for which the code as data is highly useful.

Of course there are costs to bear if you choose to write a site in Lisp, and the pros and cons are highly particular to your specific situation. On the positive side, I do feel that in the past 12-18 months the libraries for writing web frameworks in Lisp have matured quite a bit. This is due in part to the work ITA has sponsored on Hunchentoot and ClozureCL (both of which I highly recommend) as well as an increase in the number of lisp-based web projects that have led to a large amount of cleanup in the open-source libraries.

Elephant, CL-SQL, cl-prevalence and the postmodern libraries seem to be the most commonly used data storage solutions for website. I've been the lead Elephant developer for the past few years so have been able to add the features that helped in my own development efforts. FYI - there is a background project to make the Elephant API work natively in lisp without any reliance on Berkeley DB. You can use postmodern as a backend for the Elephant API to support scaling over multiple machines (with a non-trivial performance hit however).

Clozure CL supports native threads on Linux, Mac and Windows so you can leverage multiple cores for your front-end. I use bordeaux-threads as my API so people can choose to use other lisps and at least for my needs have not suffered for it. I've had no problems with multi-threading using CCL. Occasionally, though, I find myself having to pierce the portability veil to use a feature of the underlying lisp that isn't included in the portable APIs.

I'd be interested in other people's experience with scaling. ITA successfully uses lisp to run incredibly complicated, large-scale, highly parallel applications, but the key question is how much work does it take to accomplish this? http://itasoftware.com/careers/l_e_t_lisp.html

Quite frankly I think most startups spend too much time thinking about scaling and not enough about whether the product is the right thing. Alot of time and money can be spent solving a problem that never becomes an issue. You can probably get close to 1M hits a day on a good sized server running lisp - if you're that successful you should be able to afford to invest in scaling then.

With regard to hiring employees, I feel that if you are hiring people into an environment with an existing lisp infrastructure and culture and they can't learn Lisp and be productive in a few months or less, you simply aren't hiring the right people. I've had non-programmer freshman come up to speed in less than a month and do great work with only modest guidance. In my prior life I managed a large software development organization (40+ software engineers) and had good experiences hiring bright people and training them in the specific tools and problem domain if they weren't familiar with them.

If a given language is a good fit for your problem domain, and you find people who are good about thinking about that domain, then the strategic benefits should outweigh any training costs, assuming you are hiring people that can think and adapt. See Carl de Marken's real world experience with training people to work in lisp at the end of this post: http://www.paulgraham.com/carl.html

Cheers,
Ian

Dec 03, 2009
Thomas said...
Regarding Python:
1. Due to the existing production code, Python 2 will have better support in 5 years than Common Lisp has now;
2. Multi-process app seems like a better choice for what you're doing, regardless of the language;
3. Python is less functional than CL on paper, but in reality, you have to sacrifice a lot of CL's functional features for performance. If you want functional, you need OCaml or Haskell;
4. You'll end up doing it in Python anyway - just wait until you'll need another man on the project or, I dunno, a captcha library.

On Ruby:
1. You can pick it up in less time than learn a typical CL library;
2. You aren't obliged to use whatever someone mentions in the forums;
3. Likewise, you aren't obliged to use Rails.

On Clojure:
1. You're right, it's terribly immature, but
2. It at least makes use of JVM and Java libraries.

On Common Lisp:
1. Macros introduced lots of inconsistencies and ugliness (loop!);
2. Apart from pricey commercial edition, support is lacking;
3. Few know it, so employing another programmer will be impossible;
4. To get most of it, you'll have to sacrifice many functional features and use lots of ugly loop macros;
5. Hosting options are limited.

On Java:
1. It's still more readable than CL.

Dec 03, 2009
TheDarkTrumpet said...
@ian - Thanks for the post - the detailed answer on the libraries used really helped a lot. I've read quite a bit on these and will continue to read about them.

@Thomas - I disagree with a lot of what you posted. if there are more than 1 lisp programmer, hiring another is not *impossible*. It may be harder than finding someone in Java or C#, but by far not impossible. Loop is nice, but is not necessary and isn't critical for one's use. Loop also makes things easier to read in a lot of ways. Furthermore, macros don't really make things inconsistent, it's a way of shortening code to be more concise in certain circumstances. Do you need to use macros? no. Do they help? yeah, in some cases.

For the ruby comments - you're saying it's easier to learn Ruby than it is, say CL-PPCRE (which is a fairly large library)? No...not by a long shot, and I would know having learned and am still learning both CL and Ruby.

For the python comments. Said much of what I said before, and...you do not need to sacrifice functional aspects of CL in light of performance. If we want to talk performance, look at stuff like Ruby On Rails - which even a simple app in production can take tons of memory and CPU.

Really the crux of my entire post is using Lisp is no different than using other systems if taken from a pure coding want. From a management system, I can understand where you're coming from. For performance, though....complaining about Lisp's performance should be the *last* thing complained about when comparing it to nearly anything else out there.

Dec 03, 2009
Shaneal Manek said...
Well Thomas, I have to disagree with you on almost all those points.

For Python:
1. You could be right - I personally don't think so, but only time will tell. There's a lot of Common Lisp code out there - and it's been supported for decades.
2. You're wrong. The architecture is much more efficient if the concurrency primitive can share state (memory, data, etc) and this is possible much more easily and naturally with threads.
3. You're wrong (and frankly seem to have no idea what you're talking about). I get Tail calls for free. Closures are cheap. There is acceptable overhead for purely functional datastructures (see: Clojure).
4. You're an idiot. ITA Software has hundreds of Lisp programmers. My previous employer had many as well. I can name another half dozen companies with plenty of Lisp devs. They aren't hard to find - and Lisp is easy to learn if you're a good programmer. I personally know over a dozen Lisp devs that I'd love to hire (and likely could) if I had the need/resources. Lisp's libraries are lacking (as I admitted). But it hasn't hurt me yet. An example captcha library: http://tenkan.org/~tim/trivial-captcha/

For Ruby:
1. You're naive if you think Ruby is that easy. I've read two books and written probably 10,000 lines of code in it, and still wouldn't consider myself better than an amateur. Ruby (and even more so Rails) have a lot of deep magic that you have to understand if you want to write professional quality code.
2. But Ruby is evolving so fast that there is likely to be some significant gain to be had my using whatever is 'hot.' Each of the web servers I mentioned is substantially faster than its predecessor, for example.
3. I know I'm not - but much of the Ruby community (and many libraries/tools) are geared towards Rails.

Common Lisp:
1. You're wrong. Macros, when used well, don't introduce any more 'inconsistencies or ugliness' than functions. They are simply a tool that I can use when appropriate (one that is lacking from Python/Ruby, may I add). Loop is great. What's wrong with introducing an optimized domain specific language for common, repetitive tasks?
2. You're wrong ... I know plenty of Lisp consultants who will provide support on an as-needed basis. Clozure Associates as the obvious example.
3. Not that many - but more than enough for my needs. I would have no trouble hiring a dozen Lisp devs, if I had the need/resources. And it's easy to learn/train.
4. No you don't. Very little code is CPU bound. And when it is, a few type hints will give me performance far faster than Python/Ruby.
5. I can host on any VPS. How is that limited?

Java:
1. Really? I would consider myself an expert with Java (written on the order of 100K LOC) and it looks terrible. Doing anything non-trivial with it (anonymous classes, reflection, simulated method currying, etc) requires way too much boiler plate, indentation and curly braces. If you think Java is readable, you've never done anything real with it.

Dec 03, 2009
ieslick said...
Now, now - everyone be nice!

I think much of the reaction you see from people who have had limited experiences with Lisp is that it is poorly packaged, libraries are limited relative to other languages, poorly documented and only haphazardly supported. The module system is a hack and the build systems (asdf) are still not much better than Makefiles. There is only one editing model that captures the essence of lisp development (Emacs) so you have to buy into that too. Hosting a lisp site on a server you don't own requires full access and admin privs as opposed to some of the turn-key solutions you can get for PhP, python, ruby, etc.

And these are the first things you have to work through or get over before you can even begin to take on a significant project and appreciate all that lisp has to offer! It took some real motivation for me to get over that hump when I started (Peter's excellent PCL and lispbox really only prepare you for small projects, not real-world systems)

I'm quite sympathetic to these issues; they're all a part of the tradeoff and Thomas, while I disagree with him overall, is probably reacting in large part to these legitimate issues (and the silly parentheses).

Lisp is unreadable to people who:
1) Haven't spent much time looking at it (syntax)
2) Are only comfortable thinking in heavy Java-like OOP (semantics)
3) Haven't learned to use Emacs/SLIME tools to walk code (see above)

It's much easier to make lisp impossible to read than the average Java library. But when written right, I think those of us who are big fans of the language would argue that it's far more elegant than anything you could conceive of writing in Java.

Of course I'm totally unsympathetic with the "you'll never hire anyone" rant (see my earlier comment). If you are hiring someone into a lisp development group that is already well organized, you avoid most of the problems I mention above. If you only want to hire people who can't learn anything other than what they already know, then yes, lisp is a very poor choice and you'd be much better off with Java and less well-off with Python/Ruby.

We discussed these infrastructural/cultural problems extensively at ILC 2009, and there is great interest and many good intentions to fix the packaging, community, and documentation problems. The problem is that most experienced lisp users are good programmers, and most good programmers are kept awfully busy. Moreover, few people have Lisp programming as their day job, especially one that includes contributing to open source so there just isn't the commercial alignment that you see with other languages that have caught on more broadly.

I believe that fixing many of the aforementioned organizational issues would have a great deal of impact on Lisp adoption. If we could go further and triple the number of moderately good lisp hackers you would see a much higher degree of library support. For example, Elephant has maintained critical mass because there is always one developer in a group of I'd guess about 30-50 full or part-time users that are motivated to dive in and help maintain it. Same phenomenon applies to SLIME, SBCL, and a few other common libraries. Then there are the heroes like Edi Weitz (http://weitz.de/) who writes libraries like cl-ppcre that are so good they hardly need to be supported; if he ever stops writing lisp we're all screwed...

And of course there is the problem of the "If you don't get it you're an idiot and/or RTFM" that crops up on lisp forums and discussions and that certainly doesn't help motivate people to join the lisp culture. Fortunately this cranky cultural meme seems to be slowly changing as some of the older crowd mellows out and more new-age folks come in.

Dec 03, 2009
vseloved said...
@ieslick, you treat the Lisp world to hard in some aspects:
> The module system is a hack
I absolutely don't agree. Maybe some languages around have a comparable module systems, but most (like Python, for example) are very far beyond. What problems with the module system can you name?
> and the build systems (asdf) are still not much better than Makefiles.
An OO-build system is quite much better, though ASDF has it's shortcomings. Still better, than Python's variants (which one, btw?) though, not talking about the XML-based ones (like Java's). I'd be interested to hear, which one would you name the most advanced and why?

> Lisp is unreadable to people who:
> 1) Haven't spent much time looking at it (syntax)
The same concerns other languages more or less. It all depends on practice. (That's my experience from the languages I've learned this year: Python and Haskell)
> 2) Are only comfortable thinking in heavy Java-like OOP (semantics)
Oh yeah, are they born like that?
> 3) Haven't learned to use Emacs/SLIME tools to walk code (see above)
You can use PgUp/PgDown to walk code ;)

> It's much easier to make lisp impossible to read than the average Java library.
Examples?

Dec 03, 2009
Richard said...
@vseloved: I'd say it's possible to make Common Lisp hard to read — add lots of reader macros, heavily nest multiple-value-binds, don't destructure but instead pepper your code with caddrs etc.

Of course, *nobody does this*. It's not like C++ where almost any use of templates, operator extension, or custom macros will render your code unreadable, even ignoring the syntactic flexibility that prompts people to write style guides.

On the other hand, whilst Java rarely ventures beyond basic syntax (implementing generics being a counterexample), it can be *unreadable* because figuring out a piece of logic requires leaping from class to class, consulting Javadocs, paging up and down, trying to deduce what's what. "Pattern-heavy" Java code has a ton of implicit structure that must be teased out, and most Java code (particularly in servlets) produces enormous stack traces that indicate a complex calling chain.

In short: I find a large Common Lisp codebase to be easy to navigate, and most Lisp programmers find unnecessary complexity -- syntactic or semantic -- to be abhorrent. A large Java codebase requires extensive tool support because of its skewed abstractions. I know which one I'd rather support.
Dec 03, 2009
vseloved said...
@Richard
> On the other hand, whilst Java rarely ventures beyond basic syntax (implementing generics being a counterexample), it can be *unreadable* because figuring out a piece of logic requires leaping from class to class, consulting Javadocs, paging up and down, trying to deduce what's what. "Pattern-heavy" Java code has a ton of implicit structure that must be teased out, and most Java code (particularly in servlets) produces enormous stack traces that indicate a complex calling chain.
I have the same experience not only with Java, but with any frameworks-infected languages (but, surely in Python or Ruby you at least can stay away from such coding approaches)
Dec 03, 2009
ieslick said...
@vseloved Don't get me wrong, I love lisp and I'm a big fan and supporter. I was simply playing devils advocate to highlight that all is not love and roses when you look at it the landscape with a beginners eye. Love masks many faults. :)

asdf - critique and possible solution (http://article.gmane.org/gmane.lisp.cclan.general/807)

package system - I'll quote Fare from an ILC discussion (http://ilc2009.scheming.org/node/7)

"Because of its reliance on side-effecting a global state of the Lisp world, CL makes the modular cooperation between several Lisp threads or processes particularly difficult. Isolating code from various modules into conceptual or enforced sandboxes is nearly impossible."

"While global side-effects in defining functions and classes are a bad thing, the worst offender is the package system itself. Its flat symbol space with per-world aliasing, is useless for the modular cooperation of multiple processes or versions of software. The only symbols that can be guaranteed to be sharable between two divergent Lisp images are keywords (i.e. immutable strings). You can never rely on using a symbol to communicate across versions of the same software. And so the whole symbol infrastructure is essentially useless for programming in the large today (with persistent data and/or concurrent processes using divergent versions of the software)."

As for readability, familiarity and background are everything. I think you missed the point of that section - the short answer is that if what your'e looking at is similar to what you know, you can see the benefits. If it isn't, all you see are the problems.

Dec 03, 2009
vseloved said...
@ieslick
I know of XCVB, but don't like it's approach even more. And I agree, that ASDF is not perfect. But what I was asking for is a good example from other languages. Maybe RubyGems (with which I'm not familiar)? (And why?)

> "While global side-effects in defining functions and classes are a bad thing, the worst offender is the package system itself. Its flat symbol space with per-world aliasing, is useless for the modular cooperation of multiple processes or versions of software. The only symbols that can be guaranteed to be sharable between two divergent Lisp images are keywords (i.e. immutable strings). You can never rely on using a symbol to communicate across versions of the same software. And so the whole symbol infrastructure is essentially useless for programming in the large today (with persistent data and/or concurrent processes using divergent versions of the software)."
Yes, that is a valid point, although not universally applicable (only large distributed systems). And Fare is an idealist in language design (which is good for advancing what we have), but his arguments would hardly be applicable to the discussion on the level, that is here: at least when I try to apply them to other mentioned languages I fail to see how it will be different there.

> As for readability, familiarity and background are everything. I think you missed the point of that section - the short answer is that if what you're looking at is similar to what you know, you can see the benefits. If it isn't, all you see are the problems.
Mostly yes, although some things still stand out even for the outsiders

Dec 04, 2009
perlman said...
Well guys, now time for my opinion. Firstly, I appreciate all ur mature comments. I have no issues with people using any language, but I bet perl is most used in bioinformatics market after compiled languages (java, C, C++) for a variety of applications.

Why suddenly move topic to bioinformatics market ??? simple...Bioinformatics applications too these days also demand heavy computation multicore processing. I think that clojure/scala/java have a role to play here. Further, I am assuming that perl also can make use of multiple processors better than python/ruby. There may be a CPAN module for that already and I must check that.

Till such time, python/Ruby have no GIL issue and
Clojure/Scala become mature,
I prefer to be with perl. (I think I have future for atleast 3 years with perl)

By the way, I use perl, Catalyst for bioinformatics and write clean code. With perl, I get good productivity and performance.

Cheers,
perlman

Dec 04, 2009
neonsquare said...
@ieslick
Quoting Faré as an objective critic about CL probably isn't very wise. You could also quote Paul Graham for how bad CLOS and LOOP is or Larry Wall about Lisp-Syntax. ;-)

I really don't like the XCVB approach so far and I got the impression Faré was a bit upset because some library authors didn't accept patches he probably needs to get XCVB going. I actually found it to be quite hairy to my taste. Perhaps one needs that much hair to bend CL to the use-case within ITA they have in mind. Large scale environments certainly are different beasts.

Dec 08, 2009
Mike Kramlich said...
Python is used here-and-there behind the scenes at Postabon too.

And the iPhone app is pure Objective-C. The latter is a cumbersome language compared to things like Lisp and Python but it is a mostly necessary evil when doing iPhone development.

I wrote their iPhone app and can attest that integrating with the website -- which as Shaneal said is mainly Lisp -- was just like integrating with any other website. The client just opens a socket to some address and follows some documented protocol (in this case, HTTP and some structured data for the request and response payloads) and you're good to go.

I'm a fan of CL but I think that both the Java angle and Hickey's grasp of concurrency issues make Clojure a much more compelling choice for new projects than Lisp. Java owns the enterprise shops right now, for lots of reasons, some of them legitimate, and so you can't ignore it and that incredible tool and library support. So Clojure has a lot of potential, more than most of the other sexy "alternative" languages that are on my radar, I think.

That said, though I'm nowhere near as strong in Lisp as Shaneal, more of a newb really, I have to admit that when I first heard from him he was using Lisp it was a strong attractive feature for me from a recruiting standpoint, not a negative. In part because there are few shops that use it, so it's a rare opportunity. And in part, because yes while there may be fewer people who are skilled at it, they are almost always the better quality programmers, the "natural hacker" types, and I'd rather work with folks like that than Joe Enterprize any day. There are certain languages or tech stacks that when I hear a shop is using them I tend to yawn or laugh or roll my eyes and move on (VB, PHP, C#/.NET, COBOL, Fortran, etc.), and then there are other langs/stacks that make me perk up my ears and take a second look. Lisp is in that latter category.

Jan 09, 2010
Wiggam said...
I've been programming in Ruby about 8 years now, since before Rails was on the map.

Not long ago I read through Practical Common Lisp. I wish I had been programming in Lisp all this time. But I don't quite feel like delving into the arguments.

There's a circular problem with any argument I could throw out. If you don't already understand some Lisp, you won't really get the arguments for trying Lisp.

So the most I can say is: try it and see. If you are convinced that your non-Lisp language is the best, that's cool. Just be aware that many individuals like myself had the same outlook as you do, and many had their outlooks change.

Jan 14, 2010
Raoul Duke said...
for everybody's edification: yet another language to check out, but this one is on top of and plays well with, CL.

http://www.lambdassociates.org/qilisp.htm

Jan 14, 2010
brendanrankin said...
Regarding new languages, don't forget "Nu": http://www.programming.nu/
Jan 18, 2010
Andy said...
With regard to supporting openID, I thought you might be interested in a short howto I wrote about getting RPX up and running from hunchentoot.

http://cdoodle.blogspot.com/2010/01/using-rpx-from-hunchentoot.html

Jan 28, 2010
framiere said...
In this current configuration, hotspot is not working.

In order for Hotspot to trigger its magic, you need to extract your code into another method.
Warm-up hotspot by executing a few times this method.
Then you should experience the real speed of java.

Leave a comment...

 
Got an account with one of these? Login here, or just enter your comment below.
Posterous-login    twitter