Atlas · Details
Duck Season
Author’s note
For once I dialed in tne length about right. This one, published a month before I left for Google, is a response to someone who asked me if I am sneakly trying to get people to use Lisp, and if it would help him be lazier as a programmer.
In short, I told him no, you will have to work extra hard to use Lisp, because it is like Linux, requiring a lot of hands-on setup and maintenance compared to a more mainstream offering.
I was expecting this to be a boring read but it kept me going to the end.
AI Notes
Steve frames language design as a stereo equalizer with nine sliders — run-time speed, memory use, static type safety, runtime safety, cycle time, introspection, expressiveness, extensibility, familiarity — and scores eight languages (C, C++, Java, Perl, Ruby, Python, Lisp, ML, Haskell) across all of them in a flat table. Java wins by a nose on the average; every language has at least one 5 and at least one 1. It doubles as a working manual for matching a language to a job — Java for production-quiet work, Ruby and Lisp for tinkering and prototyping, ML and Haskell for research. The closing move: stop arguing about which language is "best," argue about which sliders the problem actually needs cranked, and adopt a tinkering language (Steve picks Gambit Scheme, Kawa, and Ruby) in your garage to help drag the field out of the Stone Age.
It is the cleanest single statement of the equalizer view of language design that threads through twenty years of Steve's writing — the same lens that powers Tour de Babel, The Universal Design Pattern, and eventually Cheese Wars. The Looney-Tunes title is doing real work: it's pointing at two parties who have been arguing for an hour about a setting they both agree is wrong.
Related listings
-
2005
Choosing Languages
Companion piece. Choosing Languages is the prose survey; Duck Season is the same survey rendered as a working spreadsheet.
-
2005
Scheming Is Believing
Two months earlier. Scheming names the slider Steve thinks the equalizer is missing — the one that lets you move the others. Duck Season is the equalizer with that slider held in mind.
-
2005
Decision Time
A few weeks later — the equalizer applied to a single problem. Duck Season is the methodology; Decision Time is the verdict.
From the peanut gallery
Read the rest of the thread · 8 more
-
I don't think "the unwinnable argument" is as futile as you make it out to be.
You ask "How would you convince a Windows fan(atic) that they should switch to Linux on their desktop?" Let's adjust it a bit and ask "how would you convince a VIM fan(atic) that they should switch to EMACS?"
The answer to that question is simple. Give a presentation where you demonstrate how ruthlessly efficient your editor makes you.
I've been using VIM pretty solidly for about seven years. I've also tried to make friends with EMACS at least twice before, including buying "Learning GNU Emacs." Despite this history, indicating that Emacs is not for me, your presentation still made me invest some serious effort into trying again (including writing elisp functions to emulate a few VIM behaviors I couldn't live without).
In the end I couldn't stick with it — I couldn't live without the modality, and I couldn't live with having to use ALT on a regular basis. But I live knowing that in some respects, I'm lacking ultimate power in my editing experience.
What I'm getting at is this. If your language/editor/religion is as good as you think it is, it should be possible for you to demonstrate its awesomeness in a compelling way. If you could write some crazy-cool LISP program, that would really force a competent programmer to stop and say "wow, that really amazing and useful thing you just did is really not possible or elegant in my favorite language X", I think that would be much more effective advocacy than making arguments that sound more like "dude, take a hit of this and you'll see this whole other world."
-
"wow, that really amazing and useful thing you just did is really not possible or elegant in my favorite language X"
Where do we have software that needs to change its behavior on the fly? That's where I'd expect to see Greenspun's Rule in action. One example that springs to mind right now is changing the configuration of a running FLApplication.
Also, what sort of reflection are you thinking of, that Lisp and Scheme don't have?
The Common Lisp spec mandates being able to traverse data structures interactively, possibly modifying them For Schemes, it's up to the implementation to provide them.
The Common Lisp Meta-Object Protocol lets you examine your classes and redefine them on the fly. The MOP is also the basis for a bunch of the Scheme object systems.
-
Interesting thoughts about adopting a language. I know, you said "adopt a Lisp", but I'm stretching a bit. A couple months ago I adopted Rebol. Not because it's the perfect language (it really, really isn't), but because I can play with it and tinker with it and write articles about it to my heart's desire, free from consequence. I don't need to evangelize it, because I don't think it's even reached enough mass where evangelizing would improve its situation. Nobody has come up to me yet saying "Why should I use Rebol?", because not enough people have heard of it. I can play, steal ideas for other projects, and apply what I've learned in my daily work. My articles make it a little easier for new users to look at it once they've heard of it, which has had the effect of adding a couple new users, bringing it a little closer to that critical mass. More importantly, it gets newbies familiar with languages that look a little funny, which will make Lisp less scary when they finally see it.
Meanwhile, I get to enjoy myself because I'm just having fun.
-
Derek — Lisp provides some reasonable facilities for building reflective systems. But that's a far cry from the standard out-of-the-box support you find in Java, Python, and Ruby (in increasing order of reflective power).
The implementation-dependence of the reflection support in both Lisp and Scheme is a problem. If you write code that relies on the implementation-dependent behavior, you've written non-portable code.
The MOP is only useful in cases where you're using classes and objects. In Ruby and Java, every bit of code is associated with a class, and you can reflect on it. For instance, in Lisp, how do you reflectively get a list of all the functions that operate on a particular data type, in a standardized way? Take Strings, for instance. In Ruby, you can do this:
"".methods.sort.grep(/!/)
=> ["capitalize!", "chomp!", "chop!", "delete!", "downcase!", "gsub!",
"lstrip!", "next!", "reverse!", "rstrip!", "slice!", "squeeze!",
"strip!", "sub!", "succ!", "swapcase!", "tr!", "tr_s!", "upcase!"]
et voila. I've got a list of all the String methods that work in-place with side-effects. And Ruby classes are open, so if I want to add new methods to class String, it's trivial:
"foobar".endsWith("bar")
Reflection only starts to become truly powerful and useful when the support for it is standardized and applies to every construct in the language.
If all of Lisp were written in CLOS, its reflection capabilities would be just as good as Ruby's, and it would be just as slow as Ruby.
This is what I mean by "fundamental tradeoffs".
Lisp is still cool, don't get me wrong. You're 100% on the mark about us having followed Greenspun's Tenth Rule — using C++ for anything bigger than a few thousand lines starts pushing in this direction. But Lisp is *desperately* in need of an update to modernize it. This kind of thing gets harder and harder with committees, and smaller Lisps with a single maintainer tend to move a lot faster.
That's why I'm leaning more towards Scheme(s). You can influence them more.
-
Nice write up — definitely more than I expected. Perhaps Arc, which is _the_ language that maybe we're all hoping for will score 5 on your matrix, on all counts. Where I also think Lisp got it wrong is not supplying the same type of libraries as Java did. If it was 1/2 as loaded with the same amount of libraries, we might've been Lisp-ing now instead of contracting Java-nitis...
-
I don't think the Lisp library scene is as bad as you make it out to be. Granted, it's far from complete, but it's really tearing along now.
If you use Common Lisp, ASDF is where it's at:
(require 'asdf-install)
(asdf-install:install 'cl-pcre)
(asdf-install:install 'clsql)
There, just like with CPAN, I installed a (kick-ass) regex lib and a DBI-like system.
ASDF is what made me finally swing to CL in the great CL-Scheme debate. Here's a list of the libraries that are currently available: http://www.cliki.net/asdf-install
As far as how to convince non-Lisp programmers that they're missing something, here's a great example that I just saw this morning: http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros
And, if you can convince someone that Lisp is the One True Language(TM), then the Vim-Emacs debate just falls over as a consequence (I was a Vim user until about a year ago, when Lisp and Haskell moved from distractions to obsessions).
Now I just wish that CL would collapse its namespaces and require TCO. Then I would stop pining for Scheme.
-
I would add another category to use when evaluating languges, "I/O and concurrency". Of course, only Gambit Scheme and Erlang would get a 5 in this category :-)
I/O and concurrency often get short shrift from most language designers (IMHO), presumably because they're considered too real-world and architecture-dependent: "just implement it in a library". But in fact I/O and concurrency should be 100% first-class concepts, and be inexpensive (i.e., "threads" should be ultra-lightweight, and I/O should have zero-copy semantics).
-
Why tinker with Lisp in the garage? Why not tinker with Smalltalk? I've been playing with a smalltalk environment on my Mac, Squeak. Also is available for other OSes I think (but I don't care). It's really cool, it's fun and interesting, and just way different.
> But look: every language has at least one "1" and
> at least one "5". Funny how it worked out that
Look again, Steve...you didn't give Perl any 5's...not even for its libraries (CPAN, anyone)? Your anti-Perl bias shows, sir....but you know what? The more I read of your blogs and the more I study and work with other languages, the more I'm starting to develop my own anti-Perl bias.
Well, maybe not anti Perl, but let's just say that I'm really interested in working less with Perl than I have been over the past 5 years.
— Dan K · April 10, 2005 09:35 PM
Sorry Dan. You're right. Perl used to have a 5 in runtime type-safety, and then for some reason I bumped it (and Ruby and Python) down a step, so Perl lost its only 5. I can't even remember why I did it. Maybe because... nah. Can't remember. Like I said, ask me on a different day, I'll give you different numbers.
— Steve Yegge · April 11, 2005 10:13 PM