Monday, April 26, 2010

Dylan and the Lisp family tree's central branch

Since the early eighties (beginning with Scheme and T), most Lisps began to settle around a common core.

(This also coincides with the point in time when static scoping was finally understood, once and for all, after a painful and embarrassing history.)

With the exception of Scheme, most Lisps don't have multi-shot continuations. They seriously complexify a language, as can be seen in weird implementation techniques like Cheney on the MTA.

It's also hard (or even impossible?) to make a good UNWIND-PROTECT in the face of multi-shot continuations. And UNWIND-PROTECT is surely one of the most important control flow operators.

So what is the common core I'm talking about? You can see it best in Dylan, I think.

First of all, a Lisp that follows this common core design can be efficiently implemented on real hardware. No need to do weird stuff like stack copying or Cheney on the MTA. In fact, Dylan has, with a bit of squinting, the same dynamic (control flow) semantics as C.

Second, the common core is simply nice to program in.

Some features of the common core:
  • lexical exits
  • unwind protection
  • condition system with restarts
  • global and lexical bindings
  • first-class functions with optional, keyword, and rest parameters
  • dynamic (thread-local) variables
  • class-based object system
  • generic functions
  • powerful macros
  • multiple return values
  • semi-functional stateful programming style
This core can be seen in languages that I consider the central branch of the Lisp family tree:
All of them are great languages, and worth detailed study.

In the future I hope to write about each of the features these languages share in more detail.

Wednesday, April 21, 2010


There is beauty in the fact that Lisp expressions are called forms.

Form is really fundamental. And so are Lisp expressions.

While Lisp expressions use a limited syntax (s-expressions) they are nevertheless fundamentally free-form.

One day we will all be programming in 2D graphics, and Lisp already accommodates these. To Lisp, it doesn't make a difference whether a form is 1D or 2D.

A form is simply something to be evaluated.

Tuesday, April 20, 2010

LISP (de)Motivator

(Thanks to Cpunx for the tagline.)

Code is (more than) data

In Lisps like Common Lisp, code is data.

(In CL, code is represented as cons lists, which totally sucks, because you can't attach any metadata (such as line number information) to the code.)

One of the insights of the "Scheme community" is that code is more than data. They found this out by investigating hygiene.

In essence, code has some features that aren't easily captured by simply using s-expressions.

Namely, code has lexical structure. Code containing LET for example introduces new bindings, and if you simply render that as lists, you're losing important information.

If you want hygiene (hint: you want it), simply using s-expressions isn't enough. You need syntax objects.

More later.

Monday, April 19, 2010

Why I ignore Clojure

Because Clojure ignores Lisp.

Put that gun down, and let me explain.

Lisp is a process. Progress is measured in decades.

Lisp gets lexical scope right, for example, simply because we have a head start of decades over the competition others.

I'm quite certain that the unwashed masses will discover macros around 2020 and hygiene around 2040.

It's simply a matter of time.

Lisp moves slooooooooooooooowly.

And because of this slowness, individual contributions simply don't matter. They're just a blip on the radar. You can measure a programmer's inexperience by the amount of saliva generated by new, unproven language features.

Yeah, great, Clojure does some newfangled stuff with persistent data structures. Well, if it works, Lisp will adopt it in a couple of decades. In the meantime, we'll just keep on using the same tools we've been using for decades, well.

Yeah, great, Clojure has some semi-solution for hygienic macros. Again, we'll see how that plays out in a couple of decades.

If you have some great new idea for PLs, you can be quite certain that Lispers heading an Ivy League university's CS dept have already tried it out, decades ago. And if it isn't in today's Lisps, it's because it didn't work.

So what do I mean when I say that Clojure ignores Lisp? Well, it ignores the fact that individual inventions in Lisp are mostly meaningless, because Lisp is a community process.

For the larger Lisp family to adopt a feature, it has to be tried out and implemented in a dozen different dialects and implementations, over the stretch of decades. Until that happens, it didn't happen.

And there have been and are so many smart people in this community, that if you think you've got the great new idea to push Lisp farther, you're wrong.

(I'm surely not one of these dweebs that say CL is the be-all/end-all of Lisps, and we should all be using it. Hell no. Everyone should be writing new Lisps! It's one of the greatest learning experiences there is.)

Now, go ahead and have fun using Clojure if it floats your boat, but stop whining about how it's a more modern or better Lisp. That doesn't make the slightest bit of sense.
Why do you glorify doing something new and stupid, when doing good things well is what people really should be admiring. — Linus Torvalds
[Update: this is a rant. I'm not writing articles. The good people at HN have pointed out the many flaws of this rant.]

Mr. Pestov @ Third World Languages Camp

The Emerging Languages Camp looks interesting, even if ole' astroturfer Tim Oh Really is sponsoring it.

My big hope is that Slava will beat some much-needed PLT-Fu into the langsmiths there. Especially Rob Pike.

Heck, Commander Pike is my hero, but his taste for PLs is simply way off. He seems to be sitting in a completely different branch of the evolutionary tree than the rest of us.

After the Lisps, I think Factor is the greatest PL today. I wouldn't want to code in it (Dup? No. *), but the general direction is totally right. Get the OO stuff right, and give everybody a run for their money, dynamicity-wise.

(* Factor coders always say that in normal Factor code, you won't use dup and consorts. However, almost all Factor code I've seen contains these, IMHO, abominations, just like every Scheme code I've ever seen implements an object system in terms of cons. Which should really lead to automatic destruction of one's computer.)

That Ragged Old Lisp

Lisp is ugly. Will always be. If you care, you're just not ready yet.

One of my big Common-Lisp-Aha!-moments was when I realized that under its ragged, shabby, muddy exterior lurked the dynamicest, funnest, object-orientedest language of all times.

Yes, the operators may be called PROGV, FMAKUNBOUND, and CDAADR. But the semantics below is just cute. PARC-cute. Industrial-strength. ANSI-standardized. ISO-standardized.

(Insert a huge hand wave here. Actually, we should have gotten rid of cons lists a long time ago, for example.)

Lisp's uglyness is like a stealth-coat, keeping it hidden from the clueless. In fact, in the Lisp I'm currently developing, I'm keeping the ugly names by design, in order to keep the wrong people out.

A great programming language can be found anywhere*. Do yourself a favor and go find the originals. And study them, until you can recite their specification by heart. Then implement them.

(* Totally false, of course. Great programming languages are few and far between.)

First post!

Welcome to the Axis of Eval, my new blog about programming (languages). With a lisp.