multipart-mixed

The Ruby vs. Lisp Debate

Lisp has a mystic aura as the "programming language to rule them all," so most hard-core geeks nurture a fascination with it. Paul Graham has written several essays extolling the virtues of Lisp, and indeed he's got reason to talk: he built what is now Yahoo! Shopping with Lisp. His famous Beating the Averages essay describes the experience.

I was curious how Ruby stacked up with the power-user features of Lisp, so I went digging for the inevitable "Ruby vs. Lisp" debate. I use Ruby these days (thanks to Rails) and I've used Lisp before (thanks to Emacs), but I haven't used either extensively enough to call myself an expert. Thus, I was curious to see the experts weigh in.

I must say upfront that my focus is narrow: I'm looking at each for the purpose of building web-based applications. Thus the discussion is not language vs. language, but language + frameworks vs. language + frameworks suited for my purpose.

Following is partly a summary of my research, but mostly a commentary on the debate itself. There's an interesting rift between the two camps, "interesting" not just for their opinions but for their perspectives.

[Update 2006-01-21] Please note this disclaimer I posted in the comments below.

The Lisp Camp

The core argument for Lisp is best expressed by Graham himself: "Lisp is so great not because of some magic quality visible only to devotees, but because it is simply the most powerful language available." Arguments about specifics inevitably dive into discussion over macros, continuations, and other language features. For reference, see the excellent debate in the comments of this article, complete with lots of code illustrations.

The Ruby Camp

Ruby, when combined with Rails to develop web-based applications, is widely considered the best thing since sliced bread. Their message, in big letters on their home page: "Ruby on Rails is an open-source web framework that's optimized for programmer happiness and sustainable productivity. It lets you write beautiful code by favoring convention over configuration."

The Difference

Put the camps near each other, and of course they clash. But here's where they miss each other: the Lisp camp is talking about powerful language features -- "Ruby will never be as powerful as Lisp." The Ruby on Rails camp is talking about getting things done today -- "I can build a cool web app in days instead of weeks or months."

The Lisp camp is good at demonstrating the superiority of Lisp as a core language. They then mention that the language is inherently extensible (via macros, for example) by the developer to meet their problem domain.

The Ruby camp, on the other hand, is starting from a Ruby already extended to meet the problem domain of web applications. Rails isn't just a set of helper classes for web stuff, it's a domain-specific language for models, controllers, and views. They've stolen one of Lisp's most prize weapons -- seamless extension of the language to match the problem -- and whacked them with it.

The professional developer simply must consider the language and its available frameworks. Much like Paul Graham's arguments above, I want to maximize the end result while minimizing my effort. The problem with most of the debate is that when people boil examples down to code, they're not solving real problems. How many times, in your professional career, have you written a function to generate a Fibonacci sequence?

I did some poking around for tutorials on building a simple, but halfway real, web application in each language. CLiki points me to this tutorial by Pieter Breed. Paul Graham also offers more technical details on how he built his applications, but his framework isn't publicly available. For Ruby on Rails there are several demonstration screencasts to watch.

Breed's Lisp-based tutorial takes me back to writing web applications circa 1998 -- writing all the SQL by hand, generating HTML in your code, etc.. Ick. Does this imply that Lisp is a bad language for web apps? No, but it implies that the frameworks (or libraries, in Lisp terms) are nowhere near as high-level as Rails. Watch the Rails "create a blog in 15 minutes" video for comparison.

[Update 2006-01-21] Frank points out in the comments that there's an excellent screencast to watch demonstrating the Lisp library Uncommon Web. This looks like a better starting point than Breed's tutorial. Also, Zak points out this HTML template library, this SQL object/relational mapping system, and other libraries in his comments. Thanks, guys!

Now I don't mean to bash Lisp here, I'm just commenting on the debate as I see it. Or, more specifically, the part of the debate I'm interested in: the best combination of freely-available language and tools for building web applications. And I define "best" in terms of "will it help me build stuff quick, and not get nasty as the application gets complex?"

Conclusion

It appears from the outside that Lisp, as a language, has the power to equal or better Ruby. But Ruby, when combined with Rails, puts you so far ahead of the game that it doesn't matter. That balance may change if the Lisp community builds their own Rails-style library, and for the sake of competition challenging everyone to get better, I hope they do.

For my own edification I plan to learn Lisp better. It'll serve me well in the short term -- I'm still an Emacs geek -- and in the long term for how it changes my thinking. Graham again: "...programming languages are not just technology, but what programmers think in. They're half technology and half religion."

But the core language is only half the picture. It turns out Ruby is a pretty darn good language. Good enough to create Rails with, and good enough to get things done, right now. As others in the debate have noted, "batteries are included." That's a winning combination.

[Update 2006-01-21] Lisp's problem is a lack of message. It's hard to tell what the Lisp community considers the best libraries and best practices for building web apps. At best, cliki.net provides an unranked laundry list of of libraries. At worst, it actively misleads potential developers by putting Pieter Breed's tutorial at the top of its "Web" section.

There are best practices common to nearly all web apps, e.g. separation of presentation and logic, and there are best practices for languages to get maximum leverage from that language's features. As such, the Lisp community needs their version of David Heinemeier Hansson to bring things together. This figure needs to provide a "happy path" which uses the power of Lisp and the best collection of its libraries to address common web application needs. (Paul Graham, you up for it?)

Comments

You might want to have a look at Lisp on Lines. Or even just Uncommon Web which it uses. Seems like you didn't do too much research.

"It appears from the outside that Lisp, as a language, has the power to equal or better Ruby. But Ruby, when combined with Rails, puts you so far ahead of the game that it doesn't matter."

What game? The "Make a DB-backed Web site" game? OK, sure.

And that's suppoed to be the take-away of Ruby vs. Lisp discussions?

Rails is an effect, not a cause, of Ruby's strength. It's just one of the more hyped examples what folks have been able to achieve with Ruby.

A major issue with Lisp, that the Ruby community overcame long before Rails, was the lack of a good set of cross-platform basic libraries, for things such as Web development, file I/O, database access, and XML processing.

When Lisp becomes as easy to install and develop with on Windows|Mac|*nix as Ruby is, then it too may be seen as the "get things done now, right now" language.

I welcome the day when folks can readily develop a Lisp app on Windows, demo on a Mac, and deploy to a Linux box, with free, highly quality tools and libraries.

Michael, I looked through several of the packages on cliki.net, and lisp-on-lines wasn't one I looked at in detail. From its description: "If you are daring, you can even try installing it.... As of right now, there are no examples, no documentation, no anything." Not exactly confidence-inspiring. I didn't look at UCW, and I'd gladly welcome more comments on it.

Please realize that I sincerely hope Lisp gets a framework like Rails which energizes the community and brings in new users. I honestly didn't want to learn Ruby, but the Rails "blog in 15 minutes" screencast convinced me to try it. So far their claims of sustainable productivity are holding water. If the same kind of thing was available for Lisp, I would have gone that direction instead -- I have some background in Lisp and I've always wanted a good excuse to dive into it fully.

The in-a-box approach of Rails isn't as popular in the Lisp community as it is in the Ruby community, but Lisp has some great tools available for creating web applications. I use TBNL, CL-WHO, CLSQL and mod-lisp. This is the same set of tools that was originally used to build Reddit

I've also used Rails.

It's easier to set up and deploy Rails. Ruby and its libraries have a sense of pragmatism that I've occasionally found lacking in Common Lisp and its libraries. For example, in CL, you can't just coerce a number to a string, which I've wanted to do many times. There's a workaround using the format function, but having to figure out things like that is annoying. If you're building a template-based, database-backed website, Rails is the best solution I've seen, but you have to do things the Rails way.

The afformentioned bag of Lisp tools is not a framework; unlike Rails, it doesn't structure your code for you. It's easier to make a mess of things, but more flexable. You can also easily use different tools if one of them isn't appropriate to what you're doing - e.g. you might want to substitute html-template for cl-who for pages that are mostly static content. I find this approach to be better suited to building a sophisticated web application, especially if you want to re-use components on different parts of the site.

Hi Josh,
if you didn't stumble upon it by now, check out the UnCommon Web movie.

You can download it i.e. from here:
http://bc.tech.coop/blog/050727.html

If you have to choose between a programming environment with great language features and one with great libraries and if you have a deadline to meet always choose the libs.

Java, Tcl, Visual Basic, Matlab: They did not become popular for their language features. Or because they gave utmost flexibility to the programmer. But they had/have great libs and let people get their jobs done.

Of course, this sounds boring to someone who does programming for the fun of programming itself. Then, you don't care if you have to re-invent the wheel for the n+1-th time. You like doing that and there might be a chance to apply this clever macro trick... :-)

Java, Tcl, Visual Basic, Matlab: They did not become popular for their language features. Or because they gave utmost flexibility to the programmer. But they had/have great libs and let people get their jobs done.

Those languages help people get _specific_ jobs done, with the libraries they provide and their relative ease of use. Try writing a wordprocessor in Matlab, a web application in Visual Basic, or anything but OO homework in Java. ;)

Don't throw out fun programming languages so quickly, some already have great libraries (Python, Ruby) and others are finally filling in the missing pieces (CL).

Thanks again to those leaving comments here and on Reddit.com. I've been impressed with the quality of the debate both here and on other blogs.

I feel the need to apologize that this article shifted focus as I was writing it, and as a result it doesn't hold together nearly as well as it should. My original intention was commentary on the debate I had seen elsewhere -- it was mostly very good points, presented very intelligently, but people seemed to be missing each other. Then about halfway through I shifted to the other question in the back of my mind: what's better, right now, for developing web applications?

As such, the conclusion doesn't follow the title, leaving a number of readers to comment, WTF? Thanks for bringing this to my attention. I've added some updates which add balance to the Lisp side, but in truth the article needs a re-write, sticking to observations on the Ruby/Lisp debate without offering my own opinion.

Lispers always argue that Lisp is fundamentally a more powerful, more extensible language. I've looked into this, and I believe them. Non-lispers retort that lisp's libraries and implementations are weak and fragmented, compared to other languages. This is also true.

Usually the debate stalls there, but people should focus on the puzzle this presents: if lisp is so wonderfully flexible, how come lispers haven't used it to build a world-beating set of libraries and frameworks? Why are all the great libraries in weaker languages? (e.g., It's thirty years older than python, but its libraries are still "catching up".)

Let me suggest the answer is the same as the question: It is /because/ lisp is so flexible, that lisp does not have world-beating libraries and frameworks.

Lisp gives the single programmer the ability to quickly build powerful extensions. Therefore, faced with a given problem, the lisp programmer is more likely to go build those extensions himself, while the non-lisper will go use someone else's code. Since the lisper is less likely to use someone else's code, he is less likely to help debug that code, less likely to contribute to it, and the end result is that lispers as a community never develop a single codebase that everyone is working to improve.

In other words, lisps's technical superiority for the individual programmer is also its weakness for its programming community. The language itself promotes fragmentation. And in the end, strong community cohesion wins out.

I think this idea is more believable than other common explanations, such as that people are too frightened by parentheses, or that macros require some special magical intellgience.

watching that UCW movie, its the first time I heard someone call Apache "Aposh" .. Aposh?

what continent do you live on my friend?

repeat after me: A-Patchy! A-Patch-ee

JEEBUS!

Very interesting (read: balanced) article.

And Josh - your post just above is one of the more insightful interpretations (or at least compelling theories) of Lisp's current (library) status I've come across.

For example, in CL, you can't just coerce a number to a string, which I've wanted to do many times.

(write-to-string 5) isn't good enough for you?

(write-to-string 5) isn't good enough for you?
No, it isn't; there are too many ways to transform an object from one type to another, and none of them are consistant. For example, let's say I have an array of characters or strings and I want a string. Should I use string, coerce or write-to-string?

(string #(#\a #\b #\c))
is the intuitive answer, but this produces a type error.

(write-to-string #(#\a #\b #\c))
does produce a string, but the string is
"#(#\\a #\\b #\\c)"
and that's not what I wanted.
(coerce #(#\a #\b #\c) 'string)
gives me
"abc"
which IS what I wanted.

Of course, if I'm converting a number, I need to use write-to-string or format.

Let's try it in Ruby (note that Ruby doesn't have characters as a separate type - I'm using single-char strings. Doing the same in the above Lisp example does not affect the results):

["a", "b", "c"].to_s
"abc"

5.to_s
"5"

I like Lisp. I prefer it to Ruby, but some things are annoyingly difficult for reasons that are, at best outdated. Coersion is one of them; I think it should just work.

Correction:

(coerce (list "a" "b" "c") 'string)

fails with a type error. To get the string I want from a list of strings, it appears the shortest way is:

(format nil "~{~a~}" (list "a" "b" "c"))

but that doesn't work for vectors. For vectors, you need:

(format nil "~{~a~}" (coerce #("a" "b" "c") 'list))

Fortunately, these format directives can correctly handle any object you're likely to give them, so here's a generic Lisp to-s:

(defgeneric to-s (object))

(defmethod to-s ((object list))
(format nil "~{~a~}" object))

(defmethod to-s ((object vector))
(format nil "~{~a~}" (coerce object 'list)))

(defmethod to-s ((object number))
(write-to-string object))

(defmethod to-s ((object character))
(string object))

(defmethod to-s ((object string))
object)

you might want to substitute html-template for cl-who for pages that are mostly static content.

Or use both, html-template for static part and cl-who for dynamic part and thats what I do.

Ruby is targetted at a specific problem. The web page says: 'interpreted scripting language for quick and easy object-oriented programming'.

Common Lisp is a specification for a general purpose language, mostly designed for complex applications.

Rails: is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.

So Rails fits nicely on top of Ruby. No wonder.

Common Lisp has lots of different application areas. Web programming is not a particular target. Lots of Lisp features are in the language for other types of applications (those who need high flexibility, are complex and still need some reasonable performance).

For example there were 'Parametric CAD' systems written in Common Lisp. Systems which have been used to design (for example) turbines for commercial aircrafts like the ones from Boeing. Was Common Lisp a particular good programming language to write a CAD system? Probably not. But they could write something on top of Lisp that helped. Like specific libraries for OpenGL, CAD objects, OpenGL-based user-interfaces, etc. If you fly with a Boeing, there is some chance that the turbines are designed by such a Lisp program. There is some chance that the airline staff is scheduled by a Lisp system and there is some chance that parts of the operations of the airport you are landing is scheduled by a Lisp system. Really.

Or another application area: AMD used a Lisp-written system to verify the elementary floating-point operations for the Athlon. Could you use Ruby for that? Probably. But it would not be easy. There is a software library written in Common Lisp (ACL2) which helped to do the task. Is Common Lisp now better than Ruby? Or just better for the task? Or better as long as the better library exists?

Sometimes problems like the coercion problem gets mentioned. Usually if one wants to get some specific combination of coercion, I'd write a simple function, and then put it in some library I always use.

Similar: CONCATENATE . Too much to type. Again I'd define a shorter version and put it in some library. These language usability problems are usually fixed in a few minutes.

But this is exactly the problem. Lisp is designed to be extensible on several levels. But many programmers are not used to that idea. They still think of a fixed static programming language like C, Pascal, ... The more experienced Lisp programmer just changes the language to some more domain specific language. Again, if you are not used to that, it may be hard to get over that hurdle.

Ruby is not specifically targetted at web apps. Rails is, and if you started reading about rails before you started reading about Ruby (pretty common these days) you can be forgiven the error.

I'd been using Ruby for about 6 months prior to those rails screencasts making their splash, and I'd already fallen in love. Ruby is "the object oriented scripting language" and I'd add to that "functional." The syntax is so clean and intuitive it makes using most other languages just... itch. I've been going through the process of translating my longer and harder to read Perl scripts into Ruby, and this is definitely where the language shines.

Lisp on the other hand seems to work best as a replacement for C in academic and highly technical settings. Or at least that's where it seems to be used.

My biggest beef right now with Ruby is that there's no way to do a fast recursive algorithm (without faking recursion in a C extension) an easy way of writing Ruby extensions in Lisp would certainly convince me to learn that proud old language.

Lisp is a inherently flexible and extendable language, becuase lisp is practically written entirely in lisp.

The reason that there are not many lib's for lisp is that there aren't alot of people to write them. The lisp "community", if you could call it that, doesn't seem to be terribly large, not to mention organized

"The reason that there are not many lib's for lisp is that there aren't alot of people to write them. The lisp "community", if you could call it that, doesn't seem to be terribly large, not to mention organized"
I agree with this, but remember that the ruby community before rails uses to be like this too.
Rails make Ruby popular, not Ruby itself although it's a great, elegant and simple language with a great potencial.
If you're a C/C++/Java/C# person, you will enjoy Ruby.
If you want to abstract yourself, "extend" the lenguage among other things you should go Lisp.

This is a shallow opinion of course, just comparing the languages without any framework/library , IDE, documentation, or anything else.

I think Lisp is also behind because in the days when CL was developing the open-source community hadn't yet solved the "compiler problem:" how to obtain robust compilers for lots of platforms. The solution before OSS came along was to design a spec and have lots of companies implement the spec in closed-source ways. Nowadays we have many languages which have only one real implementation (i.e. a "de facto" language with no spec), which is coupled with monolithic runtime libraries: Python, Perl, Ruby, PHP, etc. So the Lispers are busy fighting between different "standard" or "non-standard" extensions to the spec rather than taking the more modern approach and simply building a monolithic, de-facto language.

Of course building a monolithic, de-facto language requires that you make your language "different enough" from existing spec-based languages so that people don't constantly complain that you aren't adhering to another language's spec and forces of accretion and gravitation don't destabilize the nascent language's mass or social system.

The reason why lispers haven't built anything like Rails is that the only reason why programmers spread their code only if they seen it like something really clever, something that breaks the language. Lisp is so elastic that C,Java,Perl,Ruby-breaking tricks is something normal here, so they think they built nothing special,something what nobody needs because everyone who only knows the language can write it, if he must.

The reason why lispers haven't built anything like Rails is that the only reason why programmers spread their code only if they seem it like something really clever, something that breaks the language. Lisp is so elastic that C,Java,Perl,Ruby-breaking tricks is something normal here, so they think they built nothing special,something what nobody needs because everyone who only knows the language can write it, if he must.

This is an interesting post! I've really been enjoying Ruby's terse and orthogonal syntax. I'm digging in to Common Lisp, but I'm not familiar enough to make a fair comparison yet.

Post a comment