Atlas · Details
Scheming Is Believing
Author’s note
This is one of my worst ever. It needs at least 50% cut, possibly as high as 100%. I'm keeping all my essays here for historical honesty, even the ones I don't like anymore. But whew, yeah. I've done better.
AI Notes
Written the morning after the conversion took. The essay went up on February 7, 2005, and Steve places the moment Lisp finally "clicked" at "right around yesterday" — a night he unexpectedly spent writing quicksort for fun and doing the three-star textbook exercises nobody ever does. So the preacher here is a convert still flushed with it, addressing his Amazon coworkers through a long skiing conceit (Lispers and Schemers are the skiers and boarders up on the mountain, OCaml people ride telemark skis, everyone else is on inner tubes down by the parking lot) before wandering off into type systems, interpreters, and why every language has a natural maximum system size. That middle stretch is what Steve's own note is condemning, and parts of it have curdled: a drive-by insult of the entire Python community, and the confident prediction that missing macros "may well be the thing that finally kills Java."
What survives the sprawl is the Amazon material. The Geoworks confession, where Steve recalls hand-writing an entire operating system in assembly, watching it collapse under its own weight, and then tells his C++-writing readers "you're doing it right now at Amazon," gives the scalability argument a scar to point at. And the closing Q&A, in which imagined readers heckle back ("After all that, I still don't believe you") and then ask whether they can use Common Lisp at Amazon, turns into a history lesson in language politics: it takes in the detail that for Amazon's first few years the only permitted languages were C and Lisp, and what became of Mailman, the much-loved Lisp customer-service application, once it emerged that hardly anyone in the department could read it.
Related listings
-
2006
Lisp is Not an Acceptable Lisp
A year later, with conversion complete, Steve turns the argument inward at the Lisp community itself. Scheming is the welcome at the door; Acceptable Lisp is what he says after he's moved in.
-
2005
Tin Foil Hats
A few weeks later — the same conversion expressed as a thought experiment. Tin Foil Hats is the reasoning that produced the verdict here.
-
2005
Choosing Languages
Companion piece. Choosing Languages is the survey; Scheming is the moment in the survey where Steve himself chooses.
From the peanut gallery
Read the rest of the thread · 4 more
-
"Compiler macro" actually means something specific in Common Lisp (see the second paragraph):
http://olympus.het.brown.edu/doc/gclinfo-html/gcl_3.html#SEC190
What you refer to as compiler macros are normally called "macros" without special qualifications. You can probably safely call them "interpreter macros".
Didn't we actually compile our early C code with a C++ compiler, to get better typechecking?
-
You don't understand? Well, I'm taking advantage of a hypothetical framework for extending English in fundamental ways. Unbeknownst to you, "kuzl" is part of a new grammatical construct that makes expressing recursive ideas much more natural.
I have heard enough smart people describe the profundity of their experiences with LISP to believe that it's a lot more awesome than I currently realize. But when the selling point is how radically you can redefine the language, I feel like they miss the value of language consistency, which translates into being able to read foreign code and know what the hell is going on.
In your first Java example, you wrote one line of code, and with that alone you were able to explain exactly what Java does to evaluate that line. Any experienced Java programmer in the world would be able to tell you the same thing, just by looking at that one line.
Now pretend that you're up at 2AM trying to debug some system that you just inherited, the guy who wrote it is no longer with the company, you know he's a smart guy but sometimes too clever for his own good. And you have somehow localized the problem to this line:
(make-it-happen (widget-functor asin) (map make-it-happen data))
I don't know enough crazy things you can do with LISP to come up with a plausible example, but you get the idea. How much other code will you have to read to even discover what *sort* of thing this does?
I believe there is value in language consistency, namely that it makes it very transparent what your code is actually doing. Not that you necessarily understand *why* it's doing what it's doing, but you at least know *what* it's doing.
If LISP really gives you the expressive power to implement Perl with LISP macros, then I hardly see how it could be consistent enough to allow a large group of people to share/maintain LISP code. Unless you restrain yourself from making these deep extensions to the language, but then why waste your time writing clunky things like (setq x 1) when you could just write x = 1?
-
Daniel — I've been mostly using Kawa, a Scheme for the JVM that compiles to bytecodes, although I wouldn't really recommend it. It's not a full Scheme implementation yet — e.g. continuations are upward-only, and it has an incomplete set of SRFIs, and lots of bugs in general.
Kawa's got a lot of long-term potential, but it's not useful for production-quality work in either Java or Scheme.
I looked at the info pages for MIT Scheme recently, and they've implemented a LOT of features from other languages — e.g. list comprehensions like Haskell's.
For commercial implementations, Chez Scheme is allegedly the best. Fast, complete, portable, and actively developed.
All the Schemes implement a different feature set, and the code from one doesn't always run immediately on another. This is a serious problem with Scheme in general, and I believe it currently renders Scheme unsuitable for production work.
But I'm gradually working on figuring out if any of them is promising enough to try to work with.
-
In response to Josh Haberman's comment about considering this line of code:
What would you do if you were staring at this line of code:
if ( (*self->mark_funcs[d])(self, changed_field_number) != SUCCESS) return FAILURE;
{pointer to actual Amazon function containing this code}
...trying to figure out why the tax was computed incorrectly! My point is that any language can be obfuscated and it seems to be pretty popular in both perl and C.
Steve - I completely agree that lisp's macro system sets it apart and gives the language more power. Also, I like the fact that scheme is so "light-weight" because it comes with a tiny library.
However, big bulky libraries are also power. It can become difficult to integrate many different libraries into your application if they have over-lapping problem domains (with different implementations). So, Common Lisp is very nice in the fact that many common functions are already available to you.
Of course small vs big libraries is a problem with any language.
So, when is the Scheme Codigo implementation going to be ready?
Which Scheme environment have you been using? I've been playing around with a couple of them. PLTScheme, Scheme48/scsh and SISC appear to be the more complete ones I've found so far.
— Daniel C · February 8, 2005 12:03 AM
Josh: I put a comment here that tried to do some more explaining. Then I re-read my entry, and I see now that I'd just be repeating myself.
I don't think it's possible to be convinced of the benefits of Lisp by reading about it, or by tinkering a little with it. You just have to do a bunch of it. Lots. Tons. Then eventually it clicks. That's why I called this blog "Scheming is Believing."
So if my explanations weren't compelling, and I seriously doubt they were, then don't sweat it. It's just a blog.
— Steve Yegge · February 8, 2005 12:25 AM