Monday, April 28, 2008

XEmacs is Dead. Long Live XEmacs!

 "We're going to get lynched, aren't we?" — Phouchg


And you thought I'd given up on controversial blogs. Hah!

Preamble

This must be said: Jamie Zawinski is a hero. A living legend. A major powerhouse programmer who, among his many other accomplishments, wrote the original Netscape Navigator and the original XEmacs. A guy who can use the term "downward funargs" and then glare at you just daring you to ask him to explain it, you cretin. A dude with arguably the best cat-picture blog ever created.

I've never met him, but I've been in awe of his work since 1993-ish, a time when I was still wearing programming diapers and needing them changed about every 3 hours.

Let's see... that would be 15 years ago. I've been slaving away to become a better programmer for fifteen years, and I'm still not as good — nowhere near as good, mind you — as he was then. I still marvel at his work, and his shocking writing style, when I'm grubbing around in the guts of the Emacs-Lisp byte-compiler.

It makes you wonder how many of him there are out there. You know, programmers at that level. He can't be the only one. What do you suppose they're all working on? Or do they all eventually make 25th level and opt for divine ascension?

In any case, I'm sad that I have to write the obit on one of his greater achievements. Sorry, man. Keep up the cat blog.

Forking XEmacs

I have to include a teeny history lesson. Bear with me. It's short.

XEmacs was a fork of the GNU Emacs codebase, created about 17 years ago by a famous-ish startup called Lucid Inc., which, alas, went Tango Uniform circa 1994. As far as I know, their two big software legacies still extant are a Lisp environment now sold by LispWorks, and XEmacs.

I'd also count among their legacies an absolutely outstanding collection of software essays called Patterns of Software, by Lucid's founder, Richard P. Gabriel. I go back and re-read them every year or so. They're that good.

Back when XEmacs was forked, there were some fireworks. Nothing we haven't seen many times before or since. Software as usual. But there was a Great Schism. Nowadays it's more like competing football teams. Tempers have cooled. At least, I think they have.

As for the whole sordid history of the FSF-Emacs/XEmacs schism, you can read about it online. I'm sure it was a difficult decision to make. There are pros and cons to forking a huge open-source project. But I think it was the right decision at the time, just as decomissioning it is the right decision today, seventeen years later.

XEmacs dragged Emacs kicking and screaming into the modern era. Among many other things, XEmacs introduced GUI widgets, inline images, colors in terminal sessions, variable-size fonts, and internationalization. It also brought a host of technical innovations under the hood. And XEmacs has always shipped with a great many more packages than GNU Emacs, making it more of a turnkey solution for new users.

XEmacs was clearly an important force helping to motivate the evolution of GNU Emacs during the mid- to late-1990s. GNU Emacs was always playing catch-up, and the dev team led by RMS (an even more legendary hacker-hero) complained that XEmacs wasn't really playing on a level field. The observation was correct, since XEmacs was using a Bazaar-style development model, and could move faster as a direct consequence.

A lot of people were switching over to XEmacs by the mid-1990s: the fancy widgets and pretty colors attracted GNU Emacs users like moths to a bug-zapper.

Problem was, it could actually zap you.

The downside of the Bazaar

I personally tried to use XEmacs many times over a period of many years. I was jealous of its features.

However, I never managed to use XEmacs for very long, because it crashed a lot. I tried it on every platform I used between ~1996 and 2001, including HP/UX, SunOS, Solaris, Ultrix, Linux, Windows NT and Windows XP. XEmacs would never run for more than about a day under moderate use without crashing.

I've argued previously that one of the most important survival traits of a software system is that it should never reboot. Emacs and XEmacs are at the leading edge of living software systems, but XEmacs has never been able to take advantage of this property because even though it can live virtually forever, it's always tripping and falling down manholes.

Clumsy XEmacs. Clumsy!

I assume its propensity for inopportune heart attacks is a function of several things, including (a) old-school development without unit tests, (b) the need to port it to a gazillion platforms, including many that nobody actually uses, (c) a culture of rapid addition of new features. There are probably other factors as well.

I'm just speculating though. All I know is that it's always been very, very crashy. It doesn't actually matter what the reasons are, since there's no excuse for it.

Interestingly, most XEmacs users I've talked to say they don't notice the crashing. I'm sure this is because it's all relative. XEmacs doesn't crash any more often than Firefox, for instance. Probably less often. When Firefox crashes I make a joke about it and restart it, because the crashing rarely has an impact. It even restores your state properly most of the time, so it's just a minor blip, an almost trivial inconvenience, so long as whatever text field you happen to be editing has an auto-save feature. And most of the good ones do.

XEmacs may crash even less than Eclipse and IntelliJ. Crashing editors usually aren't a big problem. Programmers all learn the hard way to save their buffers frequently. For me, saving is like punctuation; I save whenever my typing pauses, out of reflex. Doesn't matter whether it's Emacs or NeoOffice or GMail or... do I use any other apps? Oh yeah, or the Gimp. When I pause, I save, and if you're a programmer I bet you do too. So occasional crashes may seem OK.

Another reason the crashes aren't called out more often is that most Emacs and XEmacs users are at best casual users. They open up an {X}Emacs session whenever they need to edit a file, and close it when they're done. It's just Notepad with colors and multi-level Undo.

If your average session length is shorter than the editor's MTBF, then yeah, you're not going to notice much crashing.

In contrast, your more... ah, seasoned (read: fanatical) Emacs users gradually come to live in it. Anything you can't do from within Emacs is an annoyance. It's like having to drive to a government building downtown to take care of some random paperwork they should have been offering as an online service a decade ago. You can live with it, but you're annoyed.

Even Firefox, the other big place I live, really wants to be Emacs. Tabs don't scale. Tabbed browsing was revolutionary in the same way adding more tellers to a bank was revolutionary: it's, like, 4x better. w00t. Emacs offers the unique ability to manage its open buffers in another first-class buffer, as a list. Imagine what your filesystem life would be like if the only view of a directory was one tab per file. Go to your pictures directory and watch it start vomiting tabs out like it tried to swallow a box of chiclets. Fun!

I feel sad when I see Eclipse users with fifty open tabs, an army of helpful termites eating away at their screen real-estate and their time.

I have a feeling I've veered off course somewhere... where was I? Oh yeah. Crashing.

So XEmacs has never been a particularly good tool for serious Emacs users because even though it's written in C, it crashes like a mature C++ application. You know the drill: major faceplants, all the fugging time.

Your ability to become an inhabitant of Emacs is gated by how stable it is. GNU Emacs has always been famously stable. Sure, the releases happen less frequently than presidential inaugurations. Sure, for a long time it always lacked some XEmacs feature or other. But it's really, really stable. Its MTBF is measurable in weeks (or even months, depending on what you're doing with it) as opposed to hours or days.

Emacs, like Firefox, can be configured to back up your state periodically, so that in theory it can recover after a crash. That's part of the problem: you didn't actually have to configure Firefox to get that behavior. It does it automatically. And to be honest, I've never had much luck with the Emacs save-state facilities. I'm a pretty competent elisp hacker these days, but the desktop.el has never worked reliably for me. I could probably get it to work, but I've always found it easier to write specialized startup "scripts" (lisp functions) that load up particular favorite configurations.

If I can't get desktop-save working, I'd guess that fewer than 1/10th of 1 percent of Emacs users use that feature. So crashes blow everything away.

If the state isn't being auto-saved, the next best thing is for it not to crash.

XEmacs never got that right.

Don't get me wrong...

I just realized I'm going to get screamed at by people who think I'm just an XEmacs-hater slash GNU-fanboy.

Make no mistake: I'm a fan of XEmacs. I think it was a great (or at least, necessary) idea in 1991. I think the execution, aside from the stability issue, was top-notch. I think it had a good architecture, by and large, at least within the rather severe constraints imposed by Emacs Lisp. I think it spurred competition in a healthy way.

I think the XEmacs development team, over the years, has consisted of engineers who are ALL better than I am, with no exceptions. And I even like certain aspects of the interface better, even today now that GNU Emacs has caught and surpassed XEmacs in features. For instance, I like the XEmacs "apropos" system better.

If you're going to scream at me for irrational reasons, it really ought to be for the right irrational reasons. Legitimate dumb reasons for screaming at me include: you're lazy and don't want to learn anything new; you invested a lot of time in XEmacs and don't see why you should be forced to switch; you are a very slow reader, causing you to skip three out of every five words I write, resulting in your receipt of a random approximation of my blog content, with a high error bar; you're still mad about my OS X blog. All good bad reasons.

Heck, you could even scream for rational reasons. Perhaps you have a philosophical beef with the FSF or GPL3. Perhaps XEmacs still has some vestiges of feature support that do not yet exist in GNU Emacs, and you truly can't live without them. I would think you're being a teeny bit uptight, but I would respect your opinion.

Whatever you do, just don't yell at me for thinking I'm dissing XEmacs or taking some sort of religious stance. Far from it. I just want a unified Emacs-o-cratic party.

XEmacs vs. GNU Emacs today

GNU Emacs pulled into the lead in, oh... I'd say somewhere around maybe 2002? 2003? I wasn't really keeping track, but one day I noticed Emacs had caught up.

Even today I maintain XEmacs/FSF-Emacs compatibility for my elisp files – some 50k lines of stuff I've written and maybe 400k lines of stuff I've pilfered from EmacsWiki, friends, and other sources. I still fire up XEmacs whenever I need to help someone get un-stuck, or to figure out whether some package I've written can be coerced to run, possibly in restricted-feature mode, under XEmacs.

For years I chose stability over features. And then one day GNU Emacs had... well, everything. Toolbars, widgets, inline images, variable fonts, internationalization, drag-and-drop in and out of the OS clipboard (even on Windows), multi-tty, and a long laundry-list of stuff I'd written off as XEmacs-only.

And it was still stable. Go figure.

I don't have the full feature-compatibility list. Does it even exist? You know, those tables that have little red X's if the Evil Competitor product is missing some feature your product offers, and little green checkmarks, and so on. We ought to make one of those. It would be useful to know what (if any) XEmacs features are preventing the last holdouts from migrating to FSF Emacs.

But for the past five years or so, just about every time an XEmacs user on a mailing list has mentioned a feature that's keeping them from switching, it's been solved.

If GNU Emacs isn't a perfect superset of XEmacs yet, I'm sure we could get it there if we had the big unified-platform carrot dangling in front of us. And I bet it's pretty close already.

Features and stability aside, XEmacs is looking pretty shabby in the performance department. Its font-lock support has never been very fast, and a few years back GNU Emacs took a giant leap forward. XEmacs can take 4 or 5 seconds or longer to fontify a medium-sized source file. Sure, it shows that big progress bar in the middle of the screen, so you know it's not dead, but when you're used to it being almost instantaneous, coming back to XEmacs is a real shocker.

And XEmacs has bugs. Man, it has a lot of bugs. I can't begin to tell you how many times I've had to work around some horrible XEmacs problem. It has bugs (e.g. in its fontification engine and cc-engine) that have been open for years, and they can be really painful to work around. I've had to take entire mode definitions and if-xemacs them, using an ancient version of the mode for XEmacs because nothing even remotely recent will run.

You may not notice the bugs, but as elisp developers, we feel the pain keenly.

Fundamental incompatibilities

As if issues with stability, performance and bugs weren't enough, XEmacs has yet another problem, which is that its APIs for dealing with UI elements (widgets and input events, but also including things like text properties, overlays, backgrounds and other in-buffer markup) are basically completely different from their GNU-Emacs counterparts. The two Emacsen share a great deal of common infrastructure at the Lisp level: they have mostly compatible APIs for dealing with files, buffers, windows, subprocesses, errors and signals, streams, timers, hooks and other primitives.

But their APIs range from mildly to completely different for keyboard and mouse handling, menus, scrollbars, foreground and background highlighting, dialogs, images, fonts, and just about everything else that interfaces with the window system.

The GUI and display code for any given package can be a significant fraction of the total effort, and it essentially has to be rewritten from scratch when porting from GNU Emacs to XEmacs or vice-versa. Unsurprisingly, many package authors just don't do it. The most famous example I can think of is James Clark's nxml-mode, which claims it'll never support XEmacs. I found that pretty shocking, since I thought it was basic Emacs etiquette to try to support XEmacs, and here James was cutting all ties, all public about it and everything. Wow.

But I totally understand, since I really don't want to rewrite all the display logic for my stuff either.

I'll be the first to admit: the API discrepancies are not XEmacs's fault. I can't see how they could be, given that for nearly all these features, XEmacs had them first.

For a developer trying to release a productivity package, it doesn't really matter whose fault it is. You target the platform that will have the most users. I don't know what XEmacs's market share is these days, but I'd be very surprised if it's more than 30%. That's a big number, but when you're an elisp hacker creating an open-source project in your limited spare time, that number can start looking awfully small. Teeny, even.

XEmacs should drop out of the race

At this point it's becoming painful to watch. GNU Emacs is getting all the superdelegates. That warmonger VIM is sitting back and laughing at us. But XEmacs just won't quit!

I'm sure there are a few old-timers out there who still care about the bad blood that originally existed between the two projects. To everyone else it's ancient history. As far as I can tell, there has been an atmosphere of polite (if subdued) cooperation between the two projects. Each of them has incorporated some compatibility fixes for the other, although it's still mostly up to package authors to do the heavy lifting of ensuring compatibility, especially for display code.

I haven't seen any XEmacs/GNU-Emacs flamewars in a long time, either. We're all just *Emacs users, keeping our community alive in the face of monster IDEs that vomit tabs, consume gigabytes of RAM, and attract robotic users who will probably never understand the critical importance of customizing and writing one's own tools.

When the Coke/Pepsi discussion comes up these days, it's usually an XEmacs user asking, in all seriousness, whether they should transition to GNU Emacs, and if so, would someone volunteer to help migrate their files and emulate their favorite behaviors.

Yes, someone will volunteer. I promise.

The dubious future of Emacs

I've got good news and bad news.

The good news is: Emacs is a revolutionary, almost indescribably QWAN-infused software system. Non-Emacs users and casual users simply can't appreciate how rich and rewarding it is, because they have nothing else to compare it to. There are other scriptable applications and systems out there — AppleScript, Firefox, things like that. They're fun and useful. But Emacs is self-hosting: writing things in it makes the environment itself more powerful. It's a feedback loop: a recursive, self-reinforcing, multiplicative effect that happens because you're enhancing the environment you're using to create enhancements.

When you write Emacs extensions, sometimes you're automating drudgery (always a good thing), sometimes you're writing new utilities or apps, and sometimes you're customizing the behavior of existing utilities. This isn't too much different from any well-designed scriptable environment. But unlike in other environments, sometimes you're improving your editing tools and/or your programming tools for Emacs itself. This notion of self-hosting software is something I've been wanting to blog more about, someday when I understand it better.

Eclipse and similar environments want to be self-hosting, but they're not, because Java is not self-hosting. In spite of Java's smattering of dynamic facilities, Java remains as fundamentally incapable of self-hosting as C++. Self-hosting only works if the code can "fold" on itself and become more powerful while making itself smaller and cleaner. I'm not really talking about macros here, even though that's probably the first thing you thought of. I'm thinking more along the lines of implementing JITs and supercompilers in the hosted runtime, rather than in the C++ or Java "hardware" substrate, which is where everyone puts them today.

I suspect (without proof) that in self-hosted environments, you can eventually cross a threshold where your performance gains from features implemented in the hosted environment outpace the gains from features in the substrate, because of this self-reinforcing effect: if code can make _itself_ faster and smarter, then it will be faster and smarter at making itself faster and smarter. In C++ and Java, making this jump to the self-reinforcing level is essentially intractable because, ironically, they have so many features (or feature omissions) for the sake of performance that they get in their own way.

To be sure, Emacs, the current crop of popular scripting languages, and other modestly self-hosting environments are all pretty far from achieving self-reinforcing performance. But Emacs has achieved it for productivity – at least, for the relatively small percentage of Emacs users who learn enough elisp to take advantage of it. There are just enough of us doing it to generate a steady supply of new elisp hackers, and the general-purpose artifacts we produce are usually enough to keep the current crop of casual users happy.

The bad news: the competition isn't the IDEs

I've argued that Emacs is in a special self-reinforcing software category. For productivity gains, that category can only be occupied by editors, by definition, and Emacs is currently way ahead of any competition in most respects. So most Emacs users have felt safe in the assumption that IDEs aren't going to replace Emacs.

Unfortunately, Emacs isn't immunized against obsolescence. It still needs to evolve, and evolve fast, if it's going to stay relevant. The same could be said of any piece of software, so this shouldn't be news. But it's particularly true for Emacs, because increasing numbers of programmers are being lured by the false productivity promises of IDEs.

They really are false promises: writing an Eclipse or IntelliJ (or God help you, Visual Studio) plugin is a monumental effort, so almost nobody does it. This means there's no community of building and customizing your own tools, which has long been the hallmark of great programmers. Moreover, the effort to create a plugin is high enough that people only do it for really significant applications, whereas in Emacs a "plugin" can be any size at all, from a single line of code up through enormous systems and frameworks.

Emacs has the same learning-curve benefit that HTML had: you can start simple and gradually work your way up, with no sudden step-functions in complexity. The IDEs start you off with monumental API guides, tutorials, boilerplate generators, and full-fledged manuals, at which point your brain switches off and you go over to see what's new on reddit. ("PLEASE UPMOD THIS PIC ITS FUNNY!")

And let's not even get into the Million Refactorings yet. It's a blog I've been working on for years, and may never finish, but at some point I'd like to try to show IDE users, probably through dozens or even hundreds of hands-on examples I've been collecting, that "refactoring" is an infinite spectrum of symbol manipulation, and they have, um, twelve of them. Maybe it's thirteen. Thirteen out of infinity – it's a start!

Programmers are being lured to IDEs, but the current crop of IDEs lacks the necessary elements to achieve self-hosting. So the only damage to Emacs (and to programmers in general) is that the bar is gradually going down: programmers are no longer being taught to create their own tools.

IDEs are draining users away, but it's not the classic fat-client IDEs that are ultimately going to kill Emacs. It's the browsers. They have all the power of a fat-client platform and all the flexibility of a dynamic system. I said earlier that Firefox wants to be Emacs. It should be obvious that Emacs also wants to be Firefox. Each has what the other lacks, and together they're pretty damn close to the ultimate software package.

If Emacs can't find a way to evolve into (or merge with) Firefox, then Firefox or some other extensible browser is going to eclipse Emacs. It's just a matter of time. This wouldn't be a bad thing, per se, but there's a good chance it would be done poorly, take forever, and wind up being less satisfying than if Emacs were to sprout browser-like facilities.

Emacs as a CLR

So Emacs needs to light a fire and hurry up and get a better rendering engine. Port to XUL, maybe? I don't know, but it's currently too limited in the application domains it can tackle. I realize this is a very hard problem to solve, but it needs to happen, or at some point a rendering engine will emerge with just enough editing power to drain the life from Emacs.

Emacs also needs to take a page from the JVM/CLR/Parrot efforts and treat itself as a VM (that's what it is, for all intents) and start offering first-class support for other languages. It's not that there's anything wrong with Lisp; the problem is X programmers. They only want to use X, so you have to offer a wide range of options for X. Emacs could be written in any language at all, take your pick, and it wouldn't be good enough.

RMS had this idea a long, long time ago (when he was making the rather controversial point that Tcl isn't a valid option for X), and it eventually led to Guile, which led more or less nowhere. Not surprising; it's a phenomenally difficult challenge. There are really only two VMs out there that have achieved even modest success with hosting multiple languages: the CLR and the JVM. CLR's winning that race, although it's happening in a dimension (Windows-land) that most of us don't inhabit. Parrot is... trying really hard. Actually, I should probably mention LLVM, which (like Parrot) was designed from the ground up for multi-language support, but took a lighter-weight approach. So let's call it four.

In any case, it's a small very group of VMs, and they still haven't quite figured out how to do it: how to get the languages to interoperate, how to get languages other than the first to perform decently, and so on.

This is clearly one of the hardest technical challenges facing our industry for the next 10 years, but it's also one of the most obviously necessary. And Emacs is going to have to play that game. I'm not talking about hacked-together process bridges like PyMacs or el4r, either — I mean first-class support and all that it entails.

I've mentioned the rendering engine and the multi-language support; the last major hurdle is concurrency. I don't know the answer here, either, but it needs an answer. Threads may be too difficult to support with the current architecture, but there are other options, and someone needs to start thinking hard about them. Editing is becoming a complicated business — too complicated for hand-rolling state machines.

Compete or die

So Emacs has some very serious changes ahead.

Let's face it: we're not going to see real change unless ALL the Emacs developers out there – today's crop of JWZs – band together to make it happen. But today we're divided. Two groups of brilliant C hackers working on separate, forked code bases? That's bad. Two groups of maniacal elisp hackers working on incompatible packages, or at best wasting time trying to achieve compatibility? Also bad.

Developers are starting to wake up and realize that the best "mainstream" extensible platform (which excludes Emacs, on account of the Lisp) is Firefox or any other non-dead browser (which excludes IE). Dynamic typing wins again, as it always will. Dynamic typing, property-based modeling and non-strict text protocols won the day for the web, and have resisted all incursions from heavyweight static replacements. And somehow the web keeps growing, against all the predictions and lamentations of the static camp, and it still works. And now the browsers are starting to sprout desktop-quality apps and productivity tools. It won't be long, I think, before the best Java development environment on the planet is written in JavaScript.

Emacs has to compete or die. If Firefox ever "tips" and achieves even a tenth of the out-of-the-box editing power of Emacs, not just for a specific application but for all web pages, widgets, text fields and system resources, Emacs is going to be toast. I may be the last rat on the ship, but I'm sure not going down with it; even _I_ will abandon Emacs if Firefox becomes a minimally acceptable extensible programmer's editor. This is a higher bar than you probably think, but it could happen.

We no longer need XEmacs to spur healthy competition. The competition is coming in hard from entirely new sources. What we need now is unity.

Then why not unify behind XEmacs?

I threw this in just in case you blew through the article, which I'd find perfectly understandable. To summarize, I've argued that XEmacs has a much lower market share, poorer performance, more bugs, much lower stability, and at this point probably fewer features than GNU Emacs. When you add it all up, it's the weaker candidate by a large margin.

Hence there's only one reasonable strategy: Hill, er, I mean XEmacs has to drop out of the race.

I'm really sorry about this. I'm a close personal friend of XEmacs, but I just can't endorse it anymore. I used to be a laissez-faire kinda guy, as long as you were using some flavor of Emacs. But at this point, if you're using XEmacs you're actively damaging not only your long-term productivity, but mine as well. So I'd like to ask you to think long and hard about switching. Soon.

If you're a local Emacs-Lisp guru, please offer your services to XEmacs users who would like to switch over. The more pain-free the migration is, the faster it will happen.

If you're a graphic artist, consider making a nice, tasteful "Euthanize XEmacs!" logo. Not that message, precisely, but something along those lines. Make sure it's tasteful. Perhaps "XEmacs is dead – long live XEmacs"? Yes, I think that would do nicely.

If you happen to know someone on the XEmacs development team, send them some chocolates, or movie tickets, or something. A thank-you, even. We should honor their service. But those guys are the most qualified on the planet to step in and start helping drive GNU Emacs forward, assuming the FSF team will have them. Emacs is in very bad shape indeed if they will not.

If you're a local system administrator, consider sudo rm -rf xemacs. Sorry, I mean consider politely asking your emacs-users mailing list if they might be willing to set a timeline for deprecating XEmacs, thereby starting the most massive flamewar in your company's history. Can't hurt!

If you're seeing red, and you skipped most of this article so you could comment on how amazingly lame this idea is, I recommend taking a little walk and getting some fresh air first.

If you're RMS, thank you for making Emacs and all that other stuff, and for keeping it free. Please be nice to those who wish to help. You're scary to the point of unapproachability, just 'cuz you're you.

XEmacs team, JWZ, and XEmacs package authors: thank you all for helping drive progress in the greatest piece of software of all time. I can only hope that someday I may have chops like that.

Now how about we turn this into the most famous reverse-fork in history?

Saturday, June 10, 2006

Shiny and New: Emacs 22

I finally upgraded to Emacs 22 a few weeks ago, and now I'm wishing I'd braved it sooner. Technically it's not released yet; I'm working from a build of a cvs snapshot from a month or so ago. But the Emacs dev team works pretty hard to make sure it has problem-free builds on a whole slew of platforms, so just following their instructions has a pretty good chance of working for you.

It's worth the effort. Truly. Reading through its NEWS file, there's just tons and tons of new functionality. It's going to take me some time, maybe a few weekends, just to absorb it all.

Personally, though, I think there are two features that by themselves justify the entire effort of upgrading: the Unicode and UTF-8 support, and the enhanced replace-regexp command.

International At Last

It's been a very long wait for Unicode and UTF-8 support, and now that I have it, I could never go back. There isn't much to say about it, except that it works. Seamlessly. It used to be hard to get international characters into and out of Emacs, because it had its own custom way of dealing with them. Now it's a snap.

In fact — here, I'll show ya. If you type C-h h, it brings up the HELLO file, which contains greetings in a variety of languages. Here's some Chinese: 中文,普通话,汉语. Here's some Korean: 안녕하세요, 안녕하십니까. Here's some Russian: Здравствуйте!

I'm not doing anything special; I'm just copying the strings out of the HELLO buffer and into my html buffer, and saving the file. I added the content-type header line in this HTML file, and all the characters just show up effortlessly in Firefox.

If you can't see them in your browser, well... Firefox is free. Or it might be a font problem on your system. As far as I'm concerned, any problems you may have in viewing them is no longer the fault of my Emacs session, which makes me Happy. Speaking as a developer who needs to internationalize every program I write, I can't begin to tell you how useful it's been to have seamless editing of utf-8 encoded files for the past month.

Right there, that feature alone is worth the upgrade.

But wait, there's more... Even though Emacs 22 has a bunch of noteworthy and exciting new features, blah blah blah, I'm going to blithely ignore them all today and focus with single-minded zeal on just one feature. It has a teeny tiny entry in the NEWS file; it's barely mentioned, really. I'm sure it was a thousand times less work than the UTF-8 support, but even so, it might well be strong enough on its own to justify the (moderate) pain of upgrading from Emacs 21.

Take a look at my examples and see if you agree!

Replacement Super-Powers

Emacs 22 sports an amazing new editing feature that's had me drooling in anticipation since I first heard about it, maybe six or eight months ago. As you can well imagine, that's a lot of drool.

And what might the feature be, you ask? Well, they've enhanced M-x {query-}replace-regxp to accept lisp expressions to be evaluated in the replacement string.

That might not seem like a big deal, so let's run through some examples, from simple to very fancy.

Example: Changing Case in Replacement Strings

Have you ever wanted to change the case of certain letters in the replacement string for M-x replace-regexp? It used to be a real pain; you either had to write a Lisp function or fix them all by hand. Now it's trivial.

As a simple demonstration, let's say you have a list of names that you need capitalized, like so:

bob
sue
ralph
alice
jimmy
preston
billy joe jim bob

It's a contrived example, since Emacs already has M-x capitalize-region. Or you could use C-u 10 M-x capitalize-word. But let's try it with the new replace-regexp evaluation feature to see how it works.

It's just like a normal M-x {query-}replace-regexp, but you'll prefix any lisp expressions in the replacement string with the sequence `\,' (i.e., a backslash and a comma). In this case, we match the whole word, and invoke the Emacs-Lisp function `capitalize' to capitalize the word we just matched:

M-x replace-regexp
Replace regexp: \(\w+\)
Replace regexp with: \,(capitalize \1)

and we wind up with each word capitalized, just like we wanted:

Bob
Sue
Ralph
Alice
Jimmy
Preston
Billy Joe Jim Bob

Unlike the capitalize-{word/region} commands, which have hardwired behavior, the {query-}replace-regexp commands give us tremendous flexibility. For instance, we could have capitalized the last letters of the names instead, by splitting each word into two regexps, with the second regexp matching just the last character. Then it's a simple matter to reconstruct the word with the last letter capitalized:

M-x replace-regexp
Replace regexp: \(\w+\)\(\w\)
Replace regexp with: \1\,(capitalize \2)

..to get the reverse capitalization we wanted:

boB
suE
ralpH
alicE
jimmY
prestoN
billY joE jiM boB

For a somewhat more realistic example, let's say you've defined some "getter" functions in a Java class, like so:
  public Relative father() { return this.father; }
public Relative mother() { return this.mother; }
public Relative sister() { return this.sister; }
public Relative brother() { return this.brother; }
public Relative auntie() { return this.auntie; }
public Relative uncle() { return this.uncle; }
...
and your code reviewer wants you prepend the word "get" to each of them.

Well, this is a classic refactoring situation ("rename method"), but you're going to have to invoke the refactoring manually for each method, and you may have hundreds of them.

If these methods have been around a while, and they're being referenced by many external callers, then you're safest using a refactoring tool. You may even consider writing a one-off refactoring script, perhaps in Jython or Mozilla Rhino, that makes programmatic use of either your IDE's refactoring APIs or a lower-level tool such as ANTLR or JavaCC.

Whew! That's going to be a lot of work, no matter how you slice it. And if you've published your APIs externally, then you're screwed; all you can do is @deprecate the old names and hope people stop using them someday.

But that's why you get your code reviews done early, right? In many real-world situations, you're performing a rename-method on a new class that has no external callers yet. And in those situations, Emacs 22 will get the job done far faster than a refactoring IDE can.

In this case, we'd just do a straightforward replacement with capitalization, similar to the one in our last example, like so:
M-x replace-regexp
Replace regexp: \(public Relative \)\(\w\)\(\w+\)
Replace regexp with: \1get\,(capitalize \2)\3
Et voilà: <-- (p.s.: C-x 8 ` a gives you that neat 'à' character.)
  public Relative getFather() { return this.father; }
public Relative getMother() { return this.mother; }
public Relative getSister() { return this.sister; }
public Relative getBrother() { return this.brother; }
public Relative getAuntie() { return this.auntie; }
public Relative getUncle() { return this.uncle; }
...
Even if you do most of your coding in the comfy confines of a visual IDE, it can be awfully handy to keep Emacs around for your fine-grained text surgery.

Now we can move on to some more interesting examples, so you can feel you got your money's worth out of today's blog entry. But first...

A Note About Emacs Regexps

Emacs regular expression syntax is very old, predating Perl 5's fancier regex syntax by almost a decade. Perl's regexp enhancements are the defacto standard, supported in virtually all major programming languages. Unfortunately, nobody has ever seen fit to retrofit poor Emacs with an alternate Perl-compatible regexp syntax, so Emacs regexps are now nonstandard and a bit awkward. Here are a few of the noteworthy differences:
  • You have to escape the (, ), {, }, and | metacharacters. That is, they're not metacharacters by default — without the backslash, they match themselves.

  • There's no '\d' shortcut for the [0-9] character class.

  • There are no lookahead or lookbehind assertions.

  • There are no direct equivalents for Perl's {n}?, {n,}?, {n,m}?, /i, /m, /s, /x, \G, or (?# ...) constructs.
But Emacs still supports some of the constructs you've come to expect:
  • You can specify exactly N repetitions with `\{N\}', and between N and M repetitions (inclusive) with `\{N,M\}'. E.g. [0-9]\{3\}-[0-9]\{4\} matches a 7-digit phone-number in the format xxx-xxxx.

  • You can have backreferences to previously matched groups in the regular expression. E.g. \(re\).*\1 matches words with "re" appearing at least twice, like carefree and première.

  • You can specify "shy" groups that don't record the match with \(?: ... \).
There are also some Emacs-specific enhancements, such as matchers for entries in the mode-specific syntax tables. The Info pages have more details on Emacs regular expressions.

If you plan to be more than a casual Emacs user, you should study the regexp syntax carefully, because there are many useful commands in Emacs that operate on regular expression matches. The better you know the Emacs-specific syntax, the more productive you'll be.

I suppose before we move on to the next example, I should preemptively answer one of the most frequently asked questions about Emacs regexps.

Q: How do I embed a newline in a regexp I'm typing into the minibuffer?

A: You use the key sequence C-q C-j. The C-q invokes the Emacs `quoted-insert' command, which basically says "insert the next character literally, without invoking any commands with it." C-j (i.e., control-j) is how a newline character is represented in Emacs.

C-q is a useful general-purpose Emacs command. Whenever you want to insert a character (in the minibuffer or a regular buffer), and it's just refusing to go in, C-q <char> will almost always do the trick.

Example: Numbering Lists

With our new replacement-with-evaluation feature, it becomes straightforward to create numbered lists. Emacs 22 has introduced a new backreferencing metacharacter, `\#', which counts the number of replacements we've done so far in the current command. So even without using any Lisp, we already have one way to make numbered lists.

Let's see... we'll need a short list of words as an example. How about all the words in /usr/share/dict/words that don't end in [a-z]? Easy enough to find out. We M-x find-file /usr/share/dict/words (only if you're on a Unix system, of course, and the location varies), and then M-x list-match [^a-z]$. Ah, perfect — our *Occur* buffer shows 32 matches:

   1987:Bogotá
5243:Fabergé
9772:Mallarmé
12044:Paraná
12499:Poincaré
16956:abbé
19923:appliqué
20932:attaché
23704:blasé
26223:café
26511:canapé
29314:cliché
31431:consommé
38981:décolleté
42995:fiancé
43623:flambé
44996:frappé
48317:habitué
58328:macramé
58898:manqué
62514:naiveté
65243:outré
66710:passé
71609:protégé
73675:recherché
76387:risqué
76847:roué
77811:sauté
82455:soufflé
89055:touché
96268:émigré
96274:études

They're prefixed by their line number, but we can make that disappear during the replacement. Let's turn them into a numbered list. First copy the matches into a new, writable buffer, then M-C-< to go to the top of the list, and then:
M-x replace-regexp
Replace regexp: \(.+:\)
Replace regexp with \#. 
Boom!
0. Bogotá
1. Fabergé
2. Mallarmé
3. Paraná
4. Poincaré
5. abbé
6. appliqué
7. attaché
8. blasé
9. café
10. canapé
11. cliché
12. consommé
13. décolleté
14. fiancé
15. flambé
16. frappé
17. habitué
18. macramé
19. manqué
20. naiveté
21. outré
22. passé
23. protégé
24. recherché
25. risqué
26. roué
27. sauté
28. soufflé
29. touché
30. émigré
31. études

Oooh, but only Computer Science students like lists numbered from zero. So let's M-x undo (using C-/ of course — everyone uses C-x C-u, but that's way too many keystrokes for something as common as Undo!) and use a tiny bit of Lisp to start the numbering at 1.

It so happens that Emacs-Lisp defines a function called 1+, which increments a number. So we can just wrap the `\#' in our replacement string with that function, like so:

\,(1+ \#).  <-- (There's a trailing space after the ".")

The result is just what we wanted:
1. Bogotá
2. Fabergé
3. Mallarmé
4. Paraná
5. Poincaré
6. abbé
7. appliqué
8. attaché
9. blasé
...

The lisp 1+ function operates on numbers, not strings, so you might have expected it to barf with a wrong-type-argument error. Our example works because the \# metacharacter returns a count of matches so far, which is a number, not a string value. In our next example, we'll have to do the conversion ourselves.

Example: Re-numbering Lists

We can use Lisp-code snippet similar to our previous one to renumber an existing list. Let's say we want to insert a word in a numbered list, like so:
1. Bogotá
2. Fabergé
3. Flambé     <-- (We inserted this one. Nice word, eh?)
3. Mallarmé
4. Paraná
5. Poincaré
6. abbé
7. appliqué
8. attaché
9. blasé
...

Easy to fix in Emacs22: place the cursor just after the word we inserted, and M-x replace-regexp `^\([0-9]+\)' with `\,(1+ (string-to-int \1))'. The result:
1. Bogotá
2. Fabergé
3. Flambé
4. Mallarmé
5. Paraná
6. Poincaré
7. abbé
8. appliqué
9. attaché
10. blasé
...

This time we used a numbered backreference (\1), which always returns a string. Don't be fooled by the fact that we appear to be matching a number: the regexp `^\([0-9]+\)' matches a string containing numeric digits, and we have to do a type conversion (using the Emacs-Lisp builtin function string-to-int) if we want to increment it.

I hope by now you're beginning to suspect that knowing a little Emacs-Lisp can help you immensely with your editing tasks. Believe it! (Not surprisingly, knowing a lot of Emacs-Lisp helps even more.)

Example: Alphabetically Numbered Lists

Let's say we have a list of 26 or fewer items, and we want to "number" it with A, B, and C rather than 1, 2, and 3.

Well, shoot. The list we've been using has 32 items. I'd prefer a list of 26 (or so) for this example.

Let's see... we can write a wee Lisp function to group the words in /usr/share/dict/words by their ending letters a-z:
(cl-prettyprint
(save-excursion
(set-buffer "words")
(loop for c from ?a to ?z
collect (let ((i 0)
(tail (string c)))
(beginning-of-buffer)
(while (re-search-forward (concat tail "$") nil t)
(incf i))
(cons tail i)))))

We just evaluate this snippet in our *scratch* buffer (by typing C-j after the last paren). It crunches the words buffer and produces:
(("a" . 1625)
("b" . 167)
("c" . 772)
("d" . 8331)
("e" . 7190)
("f" . 191)
("g" . 7401)
("h" . 991)
("i" . 457)
("j" . 4)
("k" . 784)
("l" . 2041)
("m" . 920)
("n" . 4347)
("o" . 718)
("p" . 450)
("q" . 5)
("r" . 4279)
("s" . 44857)
("t" . 4454)
("u" . 140)
("v" . 46)
("w" . 247)
("x" . 182)
("y" . 5519)
("z" . 124))

Hmmm... nothing really promising. We only get 9 words if we combine the ones ending in "q" and "j". A minor tweak to our search function will show us words ending with a doubled letter:
(cl-prettyprint
(save-excursion
(set-buffer "words")
(loop for c from ?a to ?z
collect (let ((i 0)
(tail (concat (string c) (string c))))
(beginning-of-buffer)
(while (re-search-forward (concat tail "$") nil t)
(incf i))
(cons tail i)))))

Evaluating it gives us:
(("aa" . 2)
("bb" . 3)
("cc" . 1)
("dd" . 5)
("ee" . 136)
("ff" . 75)
("gg" . 4)
("hh" . 0)
("ii" . 4)
("jj" . 0)
("kk" . 0)
("ll" . 291)
("mm" . 2)
("nn" . 38)
("oo" . 30)
("pp" . 4)
("qq" . 0)
("rr" . 13)
("ss" . 1276)
("tt" . 58)
("uu" . 1)
("vv" . 0)
("ww" . 0)
("xx" . 0)
("yy" . 0)
("zz" . 9))

Looks like we have more options with this list. Maybe if we just take the ones with a count of 5 or less... looks like 26 of them. Perfect!

We could write a little more code to extract the words matching our criteria, but it's clearly going to be fastest to eyeball it. So we call M-x list-matching-lines with the regexp \(aa\|bb\|cc\|dd\|gg\|ii\|mm\|pp\|uu\)$, and we get our list of 26 words:
   2145:Bragg
3436:Cobb
5662:Fromm
6284:Gregg
6317:Grimm
6675:Hawaii
8025:Judd
8290:Kellogg
8411:Kidd
8509:Knapp
8645:Krupp
8689:Kwanzaa
8804:Lapp
12549:Pompeii
15425:Todd
16257:Webb
16641:Yacc
17702:add
21427:baa
39145:ebb
39372:egg
46305:genii
62411:muumuu
64283:odd
72801:radii
78139:schlepp

And what a fine bunch of words they are. Just try doing that exercise in Java or C++ sometime.

In any case, now we have a list for our example, and we want to number it alphabetically. So we need to replace all the cruft up through each ':' with a counter converted to an alphabet character.

As we saw in our little function that produced this word list, Emacs uses `?c' syntax to represent characters, and internally they're just ints. So we just add the character `?a' to our `\#' counter this time, to loop through the characters 'a' to 'z':
M-x replace-regexp
Replace regexp: ^\(.+:\)
Replace regexp with: \,(+ ?a \#))

And, ladies and gentlemen... behold!
97) Bragg
98) Cobb
99) Fromm
100) Gregg
101) Grimm
102) Hawaii
103) Judd
104) Kellogg
105) Kidd
106) Knapp
107) Krupp
108) Kwanzaa
109) Lapp
110) Pompeii
111) Todd
112) Webb
113) Yacc
114) add
115) baa
116) ebb
117) egg
118) genii
119) muumuu
120) odd
121) radii
122) schlepp

D'oh!!!! I forgot to convert the counter back to a character. Haha. Oops.

After a quick C-/ to undo the operation, we can just change the replacement regexp to `\,(string (+ ?a \#))) ', and we finally have our alphabetically-enumerated word list:
a) Bragg
b) Cobb
c) Fromm
d) Gregg
e) Grimm
f) Hawaii
g) Judd
h) Kellogg
i) Kidd
j) Knapp
k) Krupp
l) Kwanzaa
m) Lapp
n) Pompeii
o) Todd
p) Webb
q) Yacc
r) add
s) baa
t) ebb
u) egg
v) genii
w) muumuu
x) odd
y) radii
z) schlepp

Or we could get capital letters by using `\,(upcase (string (+ ?a \#)))) ' instead.

Note that M-x replace-regexp has its own command history list, so you can just use up-arrow to fetch old regexps you've entered, and tweak them in place. Easier than re-entering them from scratch every time.

Some Even Snazzier Examples

So far we've used this amazing little new feature to generate (and renumber) various lists, and to change the capitalization of the replacement text on the fly (in two different ways). Both very practical and useful transformations.

In our next example, we'll assume you're working on a Java-based Web application, because your company is too lame to let you use Ruby on Rails. Hypothetically speaking, of course.

Suppose you have some JSP files containing references to various static images, e.g. <img src="images/foo_bar.gif">, and you decide you want to change them to calls into Java code to fetch the image URLs as the page is composed. So "images/foo_bar.gif" needs to change to (say) <%= StaticImageManager.FOO_BAR_GIF.getUrl()%>.

Well, clearly no fancy-pants refactoring IDE on the planet is going to be able to help you with this. If you're an Eclipse or IntelliJ or Visual Studio user, get ready for some carpal tunnel while you manually change every instance.

However, if you've followed the examples so far, you know it's trivial in Emacs 22:
M-x replace-regexp
Replace regexp: "images/\([a-z_]+\)\.\(gif\|jpg\)"
Replace regexp with: <%= StaticImageManager.\,(upcase (concat \1 "_" \2)).getUrl() %>

and they're all fixed in the blink of an eye.

But you knew that by now. This example wasn't more complex than the others, just a little longer.

It starts to get even more interesting if you permit side effects in your lisp expressions. That is to say, persistent changes to the world, whether it's Emacs variables, your buffer configuration, or even your filesystem. You have to be a bit more careful, but you can use the new replace-regexp eval feature as a powerful interactive scripting engine.

Our last example will be opening files. Often you'll find yourself looking for files using the Unix `find' command in a shell. But what if you want to open the files it turned up?

Again, it's a slightly contrived example, because it's already possible to use Unix shell commands and the "emacsclient" program to instruct Emacs to open the files you find. But it should suffice to show you what we mean by "side-effecting replacements".

A simple example should work. Let's go to our installed emacs lisp directory. Mine's /usr/share/emacs/22.0.50/lisp, which I found by looking at my `load-path' variable in my *scratch* buffer. There are various subdirectories, including textmodes/, progmodes/, and others.

To have Emacs open (say) all the elisp files beginning with the letter `x', we M-x shell, cd to /usr/share/emacs/22.0.50/lisp, and use the `find' command:
/usr/share/emacs/22.0.50/lisp>find . -name "x*.el"
./progmodes/xscheme.el
./term/x-win.el
./term/xterm.el
./obsolete/x-apollo.el
./obsolete/x-menu.el
./x-dnd.el
./xml.el
./xt-mouse.el

If you select the lines naming the 8 files above, then M-x replace-regexp will operate just in the selected region. Opening the selected files is then one easy command:
M-x replace-regexp
Replace regexp: .+
Replace regexp with: \,(find-file-noselect \&)

The files are silently opened in the background when you execute this "replacement" command. We could alternately have used `find-file' to watch them opened noisily in the foreground, but when opening lots of files I personally prefer to open them in the background. (This also makes them appear at the bottom of your buffer-list.)

Note that we used a new metacharacter here, `\&', which grabs the entire string that matched. That means we were able to omit the grouping parens. We also relied on the fact that Emacs regexps are, by default, anchored to the beginning and end of the line, so `.+' matches exactly one line, not counting the newline character. Pretty convenient!

After the replacement, the lines in your *shell* buffer are replaced with the return values of the calls to `find-file{-noselect}', which in this case is just the name of the file. But we don't really care, since it's a shell buffer; we were doing it purely for the side effect and not for the replacement.

Armed with your new-found knowledge, replace-regexp and query-replace-regexp should become some of the most powerful tools in your editing toolchest. The more experience you have with Emacs regular expressions, and with Emacs Lisp, the more bang for your buck you'll get out of this enhancement.

Example: Heading-Tag Promotion/Demotion

Oh, OK, fine. One laaaaaast example, because I just ran into it as I was putting in my final edits. You know how most browsers like to render <h1> tags in 10-foot tall letters? So we all start with <h2> or even <h3> tags and work down from there? (Those of us too lazy to muck with CSS overly much, that is. Which is most of us.)

Well, I started my blog entry today with <h1> tags, and decided to bump them all up a number (and thus down in size.)

I used to do this operation with N successive replacements, with N ranging from 2 to 5. You replace the <h5>'s with <h6>, then the <h4>'s with <h5>, and so on. No more of that hooey for me! I can renumber them all with a single replacement. You guessed it:
M-x replace-regexp
Replace regexp: <\(/?\)h\([0-9]\)>
Replace regexp with: <\1h\,(1+ (string-to-int \2))>
Zoom, zoom, zoom! All fixed in one swell foop. That's just awesome.

There's also a new query-replace-regexp-eval function, but it's not all that different from what we've talked about here, so you can read about it when you upgrade.

You are going to upgrade now, right? Well, it's your choice, it's your time. Gotta spend time to save time, as the old saying (almost) goes.

But I think it was worth it.

How do I learn this Emacs-Lisp doohickey, anyway?

It's really not too hard. Honest. Especially since I'm going to tell you some things that will make it much easier on you, because Emacs Lisp is pretty different from other languages you're used to. If you keep these points firmly in mind, learning it will be a snap, really. They're all things I wish someone had told me when I started learning elisp.

It'll Always be Useful

First, recognize that Emacs Lisp isn't going anywhere. Emacs is not going to magically become programmable in Python or Ruby or JavaScript or Perl overnight. (Or, God save us, Java or C++ or C# — all fine languages, to be sure, but they all suck at scripting.)

And judging from the last decade's pace of innovation in editing and coding environments, it will be many years before any editor begins to approach Emacs in the things Emacs does well. [The one noteworthy exception is VIM, which is also very powerful by all accounts, though I have no experience with it. If you have already developed a preference for vi over emacs, then you may experience greater happiness pursuing expertise with VIM. Psh.]

There do, in fact, exist packages that make it possible to write Emacs extensions in Python (PyMacs), Ruby (El4r), and Perl (EPL). But they're far from seamless: they're hard to install and they're hard to learn. They will only appeal to you (maybe) if you're a truly die-hard programmer in one of those languages, and you already know a fair amount of emacs-lisp, because they're closely tied to the elisp programming model. You will still need to know about buffers, overlays, markers, plists, symbols, and all the other Emacs-Lisp abstractions. And you'll have to deal with the sometimes complex mapping between language X and Emacs-Lisp.

Plus, if you want to share your extensions with your friends, they'll have to go through the install process as well. I just wouldn't go there, not if you're trying to learn how to get better with Emacs. If you're an expert in both languages, then sure. The package authors could use your help.

In the meantime, Emacs isn't going anywhere, and Emacs-Lisp isn't going anywhere, not for several decades at least, so it will benefit you to learn them deeply. It will never be obsolete knowledge. You might as well start learning it now, and reap the benefits now.

It's Kinda Like XML

You can think of Emacs Lisp as being very much like XML. There are some differences that will become apparent as you use it, but thinking of it as XML will help a lot.

In most programming languages, it's good style to avoid deeply indented code. With XML, indentation depth is entirely a function of your data domain; you don't generally think about restructuring it to avoid indentation. (Think of XHTML, for instance, in which the nesting can become arbitrarily deep.) With XML, you're building a tree structure, and it's easy to see it that way. Your XML processing tools help you manage navigating your way around complex documents.

With Lisp, you're also building an explicit tree structure. That means it's going to be indented very differently from your C/Java/Perl/Python code. The indentation is less something you decide, and more something that's decided for you based on the approach you take to the problem.

The perpetual indentation used to drive me nuts, but I've come to appreciate its advantages. I won't go into them here, but given what you know about XML, I'm sure you can imagine a few benefits without too much effort.

It Gets Better With Practice

If you do it enough, eventually you'll enjoy programming in Emacs-Lisp, no matter how much you hate it initially. You'll probably never love it, and you'll pine for a more powerful Lisp dialect, and for features from other languages you know. But like any other programming language, it becomes way more fun as you go from beginner to expert.

Programmers really hate new syntax. Most people find it harder to learn new syntax than to learn new Design Patterns or APIs or frameworks. So you'll initially dislike Emacs-Lisp's syntax; it's virtually guaranteed. Fortunately, it doesn't really have much in the way of syntax; almost everything follows the exact same s-expression form. So you should get past the syntax pretty quickly, and in a few weeks you'll start liking it just fine.

It's Oddly "Zippy"

Emacs-Lisp uses a radically different programming model from other languages. There's a strong (nearly 1:1) correspondence between what you can do in the editor and what you can do in the language. Writing elisp code is very much like scripting your actions in the editor.

For instance, to get the length of the current line (assuming the function doesn't exist), your code will remember where you are, then move the cursor to the beginning of the line, get the buffer position, jump the cursor to the end of the line, get the buffer position there, subtract the two buffer positions, return the cursor to where you were, and then finally return the value. That's a lot of moving around! [You can also use point-at-bol and point-at-eol, but in general, you still zip around a lot.]

As another example, if you wanted to determine whether any lines in the buffer started with a particular regexp, then you'd go look at them! You don't call a function that returns a list of lines in the buffer (though you could write one). You just save your position, go to the beginning of the buffer, and call next-line and looking-at to check each line against the regexp. It's like you've got a little worker-bee version of yourself, doing automatically what you could have done by hand (albeit much more slowly) using editor commands.

Over the years, they've piled up thousands of shortcut functions, and much of the time you wind up programming "normally" by invoking functions on data structures, like in other languages. But it really helps to remember that little worker bee that zips around like Feynman's lonely electron. Your coding will go more smoothly if you keep it in mind.

You can Learn From its Peers

Lastly, it's useful to know that Emacs-Lisp has a lot in common with two other famous Lisp dialects: Common Lisp and Scheme. It's arguably closer to Common Lisp, and in many ways it's inferior to both of them, but learning a little about Common Lisp or Scheme will improve your Emacs-Lisp coding dramatically. And, as it happens, there are far more books published about Common Lisp and Scheme than there are about Emacs Lisp. I'll list a few of my favorites here.

Emacs-Lisp Books

You should start with Richard M. Stallman's book. He wrote Emacs, and he wrote the Gnu Emacs Manual. It's a classic, and probably remains the best book on Emacs to date. It's a good idea to read it just to get an overview of all the things Emacs can do out of the box. Otherwise it'll be hard to know what kinds of Emacs-Lisp programs you can write.

Next, you'll want the all-time classic, Mastering Regular Expressions, by Jeffrey Friedl. Don't leave home without it.

Starting with Emacs 22, the Emacs-Lisp Reference Manual comes bundled with the distribution. I don't know if it's sold in hardcopy anymore, but it's chock-full of critically important information, so you'd do well to read it. (And re-read it periodically. It's a lot of information.)

I do have a couple of books on Emacs Lisp:

An Introduction to Programming in Emacs Lisp (Robert Chassell)
Writing GNU Emacs Extensions (Bob Glickstein)

They're not bad, but I honestly never got much from them. However, your mileage may vary. Go to Amazon, peek through them a bit, and decide for yourself whether they'll be helpful.

Common Lisp Books

There are lots — lots and lots — but these are the ones I personally found most directly relevant to helping me learn Emacs-Lisp:

ANSI Common Lisp (Paul Graham)
On Lisp (Paul Graham) — out of print, but available as a PDF. I printed it out and bound it at FedEx/Kinko's.

I own (and have read) essentially all of the other books on Common Lisp in print today, and the two above got me the furthest towards Emacs-Lisp proficiency. I'm not counting Peter Norvig's AI books, since their focus is AI, not Lisp. They're awesome books, though; I recommend them both highly.

And if you're actually trying to learn Common Lisp to use it (as opposed to applying what you can of it to Emacs), then you'd better get a copy of Peter Siebel's Book. It's essential.

Scheme Books

Again, lots to choose from, and Scheme books tend to be more didactic, so I found they had a bigger impact in terms of ingraining the core ideas of Lisp. Listed in decreasing order of mind-opening wow-ness:

Structure and Interpretation of Computer Programs — a good candidate for the "Best Computer Science Book Ever" award.

The Little Schemer — I worked through every single exercise twice: once in Scheme, once in Emacs-Lisp. Ditto for the sequel, The Seasoned Schemer, and I just started on the brand-new third volume, The Reasoned Schemer.

The Scheme Programming Language — good book, though a bit heavy going, as it's long on concepts and short on explanations. I found it well worth wrestling through, though.

Scheme is a wonderful language, and worth learning in its own right.

Caveats

If Emacs 22 goes on a horrible disk-eating rampage, don't blame me.

As one might expect of alpha software, it's got some bugs and glitches. I've never had anything really scary happen. It hasn't corrupted my data so far, and it has only crashed once or twice (i.e., far less often than the supposedly "stable" releases of XEmacs). But it occasionally does surprising things, like minimizing the entire frame if I try to 'q' (quit) certain read-only windows, or suddenly bringing up a completions buffer when I'm typing along in fundamental mode. They're rare enough not to have bothered me much.

They've also broken backwards-compatibility with several in-house functions and modes, so I've had to do some work to rewrite them. If you rely on proprietary Emacs-Lisp software as part of your job, and you're not proficient with elisp yourself, then you should make sure you have a local guru available before you upgrade to Emacs 22, or some stuff may stop working for you.

This blog entry consists, as usual, of only my very own whimsical opinions. I don't speak for my employer, nor for anyone else's employer, nor for any of the authors cited here, nor for the most excellent development teams working on Emacs, XEmacs, VIM, Eclipse, IntelliJ, Visual Studio, Firefox, and Ruby on Rails. I just speak for me.

If you didn't like this article, please be sure to run over to Reddit and call me stupid there. I'm sure people would hate to miss an opportunity to hear how you've taken such a boldly prominent and decisive stand on some random guy's personal blog.

And if you did like the article — well, go play with Emacs 22!

Sunday, November 16, 2008

Ejacs: a JavaScript interpreter for Emacs

So! I have all these cool things I want to write about, but I broke my thumbnail. Can you tell that's a long story?

See, this summer I got excited about playing guitar again. I usually switch between all-guitar and all-piano every other year or so. This summer I dusted off the guitars and learned a bunch of pieces, and even composed one. I was prepping for — among other things — a multimedia blog entry. It was going to have a YouTube video, and a detailed discussion of a wacky yet powerful music programming language you've probably heard of but never used, and generally just be really cool.

And then it all came crashing down when I busted my thumbnail off. And I mean off — it broke off at least a quarter inch below where the nail and skin meet. Ick. I just accidentally jabbed my steering wheel, and that was that.

I remember reading an interview with some dude who said he had punched a shark in the nose. He said it was like punching a steering wheel. So now I know more or less what it's like to punch a shark in the nose, I guess. There's always an upside!

Anyway, that was going to be my magnum opus (literally: Op. 1) for the year, but it fell through for now. I'll have to revisit the idea next year. My thumbnail's back, but it's been at least 2 months since I touched my guitar, so I'll have to start over again.

Work has been extraordinarily busy, what with having to collect all these Nuka-Cola Quantum bottles and so on. I'm sure you can imagine. So I haven't had much time to blog lately.

But I do like to publish at least once a month, whether or not anyone actually cares. It's been about a month, or it feels that way anyway, and all I have to show for it is this box of Blamco Mac and Cheese.

So I'm cheating this month.

You know how on Halloween how you walk around in your costume holding your little bag and you say "trick or treat", and every once in a while some asshole does a trick instead of dumping half a pound of candy into your bag? And then he has to explain to all the dumbfounded and unhappy kids that "Trick or Treat" means that a trick is perfectly legal according to the semantics of logical-OR, and the kids remember that a-hole for the rest of their childhoods and avoid his house next year?

Yeah.

So I'm doing a trick this time. Hee. It's actually kind of fun when you're on the giving end.

My trick is this: in lieu of saying anything meaningful or contemporarily relevant, I'm writing about something I did over a year ago. And there isn't much to say, so this really will be short.

Ejacs

Around a year ago, I wrote a blog called Stevey's Boring Status Update, mostly in response to wild rumors that I'd been fired from Google. Not so. Not yet, anyway.

In that blog I mentioned I was working nights part-time (among other things) on a JavaScript interpreter for Emacs, written entirely in Emacs Lisp. I also said I didn't have a name for it. A commenter named Andrew Barry suggested that I should not call it Ejacs, and the name stuck.

Ejacs is a port of Narcissus. Narcissus is a JavaScript interpreter written in JavaScript, by Brendan Eich, who by pure unexpected coincidence is also the inventor of JavaScript. Narcissus is fairly small, so I thought it would be fun to port it to Emacs Lisp.

It turns out Narcissus is fundamentally incomplete. It cheats. It's that trick guy on Halloween. Narcissus has a working parser and evaluator, but for its runtime it calls JavaScript. So it's kind of like saying you're building a car by starting from scratch, using absolutely nothing except for a working car.

This meant I wound up having to write my own Ecma-262 runtime, so that the evaluator would have something to chew on. In particular, the Ecma-262 runtime consists of all the built-in properties, functions and objects: Object, Function, Array, String, Math, Date, RegExp, Boolean, Infinity, NaN, parseInt, encodeURIComponent, etc. A whole bunch of stuff.

I basically did this by reading the ECMA-262 specification and translating their algorithms into Emacs-Lisp. That spec is lousy for learning JavaScript, but it's absolutely indispensable if you're trying to implement JavaScript.

I didn't know Emacs-Lisp all that well before I started, but boy howdy, I know it now.

Emacs actually has a pretty huge runtime of its own — bigger than you would ever, ever expect given its mundane title of "text editor". Emacs has arbitrary-precision mathematics, deep Unicode support, rich Date and Calendar support, and an extensive, fairly complete operating system interface. So a lot of the porting time was just digging through Emacs documentation (also extensive) looking for the Emacs version of whatever it was I was porting. That was nice.

I had big plans for Ejacs. I was going to make it a full-featured, high-performance JavaScript interpreter, with all the Emacs internals surfaced as JavaScript native host objects, so you could write Emacs customizations using object-oriented programming. It was totally going to be the "meow" part of the cat.

And then I broke my thumbnail.

Actually, what happened was js2-mode.

js2-mode

After I got the interpreter working, I was at this crossroads. There were two big use cases: a JavaScript editing mode, or a JavaScript Emacs development mode. Both were going to be a lot of work.

It turns out you really want the editing mode first, if possible, so that when you're doing all your JavaScript programming you have a decent environment for it. So I picked the editing mode.

Unfortunately I found the Ejacs parser wasn't full-featured enough for my editing needs, since at the time I was working on my Rhino-based Rails clone and writing tons of JavaScript 1.7 code on the JVM.

I spent a little time trying to beef up the parser, then realized it would be a lot faster to just rewrite it by porting Mozilla Rhino's parser, which is (only) about 2500 lines of Java code. Ejacs is something like 12,000 lines of Emacs-Lisp code, all told, so that didn't seem like a big deal.

So I jumped in, only to find that while the parser is 2500 lines of code, the scanner is another 2000 lines of code, and there's another 500 or so lines of support code in other files. So I was really looking at porting 5000 lines of Java code.

Moreover, the parse tree Rhino builds is basically completely incompatible with the Ejacs parse tree. It was richer and more complex, and needed more complicated structures to represent it.

So after I'd ported the Rhino parse tree, what I really had was a different code base. I went ahead and finished up the editing mode, or at least enough to make it barely workable (another 5000 lines of code), and launched it. It was a surprisingly big effort.

And it left poor Ejacs lying unused in the basement.

So today, faced with nothing to write about, I figured I'd dust off Ejacs, launch it with lots of fanfare, and then you'd hardly notice that I cheated you. Right?

You're not coming to my house next year. I can tell already.

Anyway, here's the code: http://code.google.com/p/ejacs/

There's a README and a Wiki and installation instructions and stuff. I can't remember how to put the code in SVN, and I'm having trouble finding it on the code.google.com site. As soon as I figure it out I'll also make it available via SVN.

Emacs Lisp vs. JavaScript

In the interests of having something resembling original worthwhile content today, I'll do a little comparison of Emacs Lisp and JavaScript. I know a lot about both languages now, and a few folks mentioned that a comparison would be potentially interesting.

Especially since I think JavaScript is a better language.

So... the best way to compare programming languages is by analogy to cars. Lisp is a whole family of languages, and can be broken down approximately as follows:
  • Scheme is an exotic sports car. Fast. Manual transmission. No radio.
  • Emacs Lisp is a 1984 Subaru GL 4WD: "the car that's always in front of you."
  • Common Lisp is Howl's Moving Castle.

This succinct yet completely accurate synopsis shows that all Lisps have their attractions, and yet each also has a niche. You can choose a Lisp for the busy person, a Lisp for someone without much time, or a Lisp for the dedicated hobbyist, and you'll find that no matter which one you choose, it's missing the library you need.

Emacs Lisp can get the job done. No question. It's a car, and it moves. It's better than walking. But it pretty much combines the elegance of Common Lisp with the industrial strength of Scheme, without hitting either of them, if you catch my drift.

Anyway, here's the comparison. Here's why I think JavaScript is a better language than Emacs Lisp.

Problem #1: Momentum

A recurring theme is that Elisp and JavaScript both will both exhibit a particular problem, and there are specific near-term plans to fix it in JavaScript, but no long-term plans to fix it in Elisp.

It's easier to resign yourself to a workaround when you know it's temporary. If you know the language is going to be enhanced, you can even design your code to accommodate the enhancements more easily when they appear.

People are working on improving JavaScript. It's not happening quite as fast as I'd hoped earlier this year, but it's still happening. As far as I know, Emacs Lisp is "finished" in the sense that no further evolution to the language is deemed necessary by the Emacs development team.

Problem #2: No encapsulation

Every symbol in Emacs-Lisp is in the global namespace. There is rudimentary support for hand-rolled namespaces using obarrays, but there's no equivalent to Common Lisp's in-package, making obarrays effectively useless as a tool for code isolation.

The only effective workaround for this problem is to prefix every symbol with the package name. This practice has become so entrenched in Emacs-Lisp programming that many packages (e.g. apropos and the elp elisp profiler) rely on the convention for proper operation.

The main adverse consequence of this problem in practice is program verbosity; it makes Emacs-Lisp more difficult to read and write than Common Lisp or Scheme. It can also have a non-negligible impact on performance, especially of interpreted code, as the prefix characters can approach 5% to 10% of total program size in some cases.

The problems run slightly deeper than simple verbosity. Without namespaces you have no real encapsulation facility: there is no convenient way to make a "package-private" variable or function. In practice there's little problem with program integrity; it's hard for an external package to change a "private" variable inadvertently in the presence of symbol prefixes. However, it makes it annoyingly difficult for users of the package to discern the "important" top-level configuration variables and program entry points from the unimportant ones. Elisp attempts a few conventions here, but it's a far cry from real encapsulation support.

JavaScript also lacks namespaces. They're being added in ES/Harmony, but in the meantime, browser JavaScript code typically uses the same name-prefixing practice as Emacs-Lisp.

However, JavaScript has lexical closures, which provide a mechanism for creating private names. One common encapsulation idiom in browser JavaScript is to wrap a code unit in an anonymous lambda, so that all the functions in the code unit become nested functions that close lexically over the top-level names in the anonymous lambda. This trick is nowhere near as effective in Emacs-Lisp, for several reasons:
  • elisp is not lexically scoped and has no closures
  • elisp nested defuns are still entered into the global namespace
  • CL's `flet' and `labels' are only weakly supported, via macros, and they frequently confuse the debugger, indenter, and other tools.

Some elisp code (e.g. much of the code in cc-engine) prefers to work around the namespace problem by using enormous functions that can be thousands of lines long, since let-bound variables are slightly better encapsulated. Even this is broken by elisp's dynamic scope:
(defun foo ()
(setq x 7))

(defun bar ()
(let ((x 6))
(foo)
x)) ; you would expect x to still be 6 here

(bar)
7 ; d'oh!

So let-bound variables in elisp can still be destroyed by your callee: a dangerous situation at best.

Emacs is basically one big program soup. There's almost no encapsulation to speak of, and it hurts.

Problem #3: No delegation

One of the big advantages to object-oriented programming is that there is both syntactic support and runtime support for automatic delegation to a "supertype". You can specialize a type and delegate some of the functionality to the base type. Call it virtual methods or prototype inheritance or whatever you like; most successful languages support some notion of automatic delegation.

Emacs Lisp is a lot like ANSI C: it gives you arrays, structs and functions. You don't get pointers, but you do get garbage collection and good support for linked lists, so it's roughly a wash.

For any sufficiently large program, you need delegation. In Ejacs I wound up having to implement my own virtual method tables, because JavaScript objects inherit from Object (and in some cases, Function, which inherits from Object).

Writing your own virtual method dispatch is just not something you should have to do in 2008.

Problem #4: Properties

I wrote about this at length in a recent blog post, The Universal Design Pattern. JavaScript is fundamentally a properties-based language, and it's really nice to be able to just slap named properties on things when you need a place to store data.

Emacs Lisp only offers properties in the form of simple plists – linked lists where the odd entries are names and the even entries are values. Symbols have plists, and symbols operate a little bit like very lightweight Java classes (in that they're in the global namespace), but that only gets you so far. If you want the full JavaScript implementation of the Properties Pattern, you'll have to write a lot of code.

And so I did. Your implementation choice for object property lists has a huge impact on runtime performance. Emacs has hashtables, but they're heavyweight: if you try to instantiate thousands of them it slows Emacs to a crawl. So they're no good for the default Object property list. Emacs also has associative arrays (alists), but their performance is O(n), making them no good for objects with more than maybe 30 or 40 properties.

I wound up writing a hybrid model, where the storage starts with lightweight alists, and as you add properties to an object instance, it crosses a threshold (I set it to 50, which seemed to be about right from profiling), it copies the properties into a hashtable. This had a dramatic increase in performance, but it was a lot of work.

I experimented with using a splay tree. I implemented Sleater and Tarjan's splay tree algorithm in elisp; Ejacs comes with a standalone splay-tree.el that you can use in your programs if you like. I was hoping that its LRU cache-like properties would help, but I never found a use case where it was faster than my alist/hashtable hybrid, so it's not currently used for anything.

And then in the end, after I was done with my implementation, it was a library (at least from the Emacs-Lisp side of the house). It wasn't an object system for Lisp. It's only really usable inside the JavaScript interpreter, where it has syntactic support.

You really want syntactic support. Sure, people have ported subsets of CLOS to Emacs Lisp, but I've always found them a bit clunky. And even in CLOS it's hard to implement the Properties Pattern. You don't get it by default. CLOS has lots of support for compile-time slots and virtual dispatch, but very little support for dynamic properties. It's not terribly hard to build in, but that's my point: for something that fundamental, you don't want to have to build it.

Problem #5: No polymorphic toString

One of the great strengths of JavaScript is the toSource extension. I don't know if they support it over in IE-land; I haven't been a tourist there in a very long time. But in real versions of JavaScript, every object can serialize itself to source, which can then be eval'ed back to construct the original object.

This is even true for functions! A function in JavaScript can print its own source code. This is an amazingly powerful feature.

In Emacs Lisp, some objects have first-class print representations. Lists and vectors do, for instance:

(let ((my-list '()))
(push 1 my-list)
(push 2 my-list)
(push 3 my-list)
my-list)
(3 2 1)

(let ((v (make-vector 3 nil)))
(aset v 0 1)
(aset v 1 2)
(aset v 2 "three")
v)
[1 2 "three"]


But in Emacs Lisp, many built-in types (notably hashtables and functions) do NOT have a way to serialize back as source code. This is a serious omission.

Also, trying to print a sufficiently large tree made entirely of defstructs will crash Emacs, which caused me a lot of grief until I migrated my parse tree to use a mixture of defstructs and lists. Note that simply typing the name of a defstruct, or passing over it ephemerally in the debugger, will cause Emacs to try to print it, and crash. Fun.

The problem of polymorphic debug-printing (or text-serialization) is, I think, a byproduct of Emacs not being object-oriented. If you want a debug dump of a data structure, you write a function to do it. But Emacs provides a half-assed solution: it debug-prints lists very nicely, even detecting cycles and using the #-syntax for representing graph structures (as does SpiderMonkey/JavaScript). But it has no useful debugging representation for hashtables, functions, buffers or other built-in structures, and there's no way to install your own custom printer so that the debugger and other subsystems will use it.

So it sucks. Printing data structures in Emacs just sucks.

The situation in Ecma-262-compliant JavaScript really isn't that much better, although you can at least install your own toString on the built-ins. But any competent "server-side" JavaScript implementation (i.e. one designed for writing real apps, rather than securely scripting browser pages) has a way to define your own non-enumerable properties, so you can usually override the default behavior for things like toString and toSource.

And all else being equal, at least JavaScript functions print themselves.

Emacs advantages: Macros and S-expressions

Pound for pound, Emacs Lisp seems roughly as expressive as JavaScript or Java for writing everyday code. It shouldn't be that way. Emacs Lisp ought to be more succinct because it's Lisp, but it's incredibly verbose because of the namespace problem, and it's also verbose to the extent that you want to use the properties pattern without worrying about alist or hashtable performance.

Elisp does have a few places where it shines, though. One of them is the cl (Common Lisp emulation) package, which provides a whole bunch of goodies that make Elisp actually usable for real work. Defstruct and the loop macro are especially noteworthy standouts.

Some programmers are still operating under the (ancient? legacy?) assumption that the cl package is somehow deprecated or distasteful or something. They're just being silly; don't listen to them. Practicality should be the ONLY consideration.

The cl package wouldn't have been possible without macros. JavaScript has no macros, so even though it has better support for lambdas, closures, and even (in some versions) continuations, there are still copy/paste compression problems you can't solve in JavaScript.

Emacs Lisp has defmacro, which makes up for a LOT of its deficiencies. However, it really only has one flavor. Ideally, at the very least, it should support reader macros. The Emacs documentation says they were left out because they felt it wasn't worth it. Who are they to make the call? It's the users who need them. Implementer convenience is a pretty lame metric for deciding whether to support a feature, especially after 20 years of people asking for it.

Elisp is s-expression based, which is a mixed bag. It has some advantages, no question. However, it fares poorly in two very common domains: object property access, and algebraic expressions.

JavaScript is NOT s-expression based (or it wouldn't be a successful language, many would argue), but it does offer some of the benefits of s-expressions. JSON is one such benefit. JavaScript's declarative object literals (or as a Lisp person would say, "syntax for hashes") and arrays provide a powerful mechanism for designing and walking your own declarative data structures.

JavaScript also has all the usual (which is to say, expected) support for algebraic operators. And unlike Java, JavaScript even got the precedence right, so it's not full of redundant parentheses.

Overall Comparison

In the end, it comes down to personal choice. I've now written at least 30,000 lines of serious code in both Emacs Lisp and JavaScript, which pales next to the 750,000 or so lines of Java I've crapped out, and doesn't even compare to the amount of C, Python, assembly language or other stuff I've written.

But 30,000 lines is a pretty good hunk of code for getting to know a language. Especially if you're writing an interpreter for one language in another language: you wind up knowing both better than you ever wanted to know them.

And I prefer JavaScript over Emacs Lisp.

That said, I suspect I would probably prefer Clojure over Rhino, if I ever get a chance to sit down with the durn thing and use it, so it's not so much "JavaScript vs. Lisp" as it is vs. Emacs Lisp.

I would love to see Emacs Lisp get reader macros, closures, some namespace support, and the ability to install your own print functions. This reasonably small set of features would be a huge step in usability.

However, for the nonce I'm focusing on JavaScript. I've found that JavaScript is a language that smart people like. It's weird, but I keep meeting really really smart people, folks who (unlike me) are actually intelligent, and they like JavaScript. They're always a little defensive about it, and almost a little embarrassed to admit it. But they think of it as an elegant, powerful, slightly flawed but quite enjoyable little language.

I tell ya: if you're a programming language, it's a very good thing to have smart people liking you.

It doesn't make me smart, but I kinda like it too. Even though there's (still) a lot of hype these days about Java, and people tootling on about how Java's going to be the next big Web language... I just don't see it happening. There are too many smart people out there who like JavaScript.

So enjoy the interpreter. Ejacs is just a toy, but I think it also shows a kind of promise. Scripting Emacs using JavaScript (if anyone ever actually implements it) could be really interesting. It could open up the world's most powerful, advanced editing environment to millions of people. Neat.

In the meantime, it doesn't actually do squat except interpret EcmaScript in a little isolated console, so don't get your hopes up.

Reminder — here's the Ejacs URL: http://code.google.com/p/ejacs - enjoy!

And with that, I'm off to find some Nuka-Cola Quantum. I just wish those bastards hadn't capped me at level 20.