MATHEMATICS

Minggu, 17 September 2006

Blogger's Block #1: Joelprah

Part 1 of an N-part series of short posts intended to clear out my bloggestive tract. Hold your nose!

Ever since my last entry I've had blogger's block. Haven't been able to write a thing. I've tried, but haven't made any progress on anything.

Partly it's because I hinted I'd be writing about a controversial technical topic next. I was going to, but I can't seem to bring myself to talk about it. I've tried exactly umpteen approaches, many of them over half finished. None of them quite hit the mark. You make a promise like that, and I think you'll find it hard to keep. I know I have.

It's also partly because I was finishing up a long-ish project at work, and then I went on a much-needed vacation for 2 weeks. Of course I just stayed at home and worked on a new Ruby on Rails site, which might not sound like much of a vacation to you, but if you've been working with the web technologies I've been working with lately... let's just say RoR is like having a pillow surgically removed from your face. I can breathe again.

Incidentally, my game-and-blog server has been down for a week, since I decided to shepherd it into our current century by upgrading from RedHat 7.3 to the latest Ubuntu. Wow. Ubuntu rocks. Everything just works, including apt-getting a smp kernel and rebooting. So now I can drag the server back to the dismal concrete bunker in downtown Seattle where my ISP hosts the thing.

I moved the old Drunken Blog Rants, though. They're now all hosted in
pages.google.com. They were (inexplicably, as always) getting a lot of traffic, and it was really eating into the CPU and bandwidth for my game, so I've moved them to a place where they'll presumably have better latency and availability. When my old server comes back online, I've just told Apache to do permanent redirects for the 50-odd articles.

Putting them in Google Pages was pretty easy. I eventually wound up getting to where I could port one in about 90 seconds, so the whole exercise only took a few hours. It really was the perfect place to host them: they're mostly static content, and I just needed a permanent place for them to live. Google has a way of creating things I actually use. Blogger's just good enough. The spreadsheet is just good enough (I use it for my diet log). Google Pages is just good enough. And so on. I'm living more and more in my browser now because of Google.

I work there now, you know. A teeny fish in a big ocean of brilliant people. I'll blog about that a bit in one of my upcoming bloguettes, I think.

So where was I? Oh yeah. Blogger's block. It wasn't just the Mystery Tech Topic that's had me blocked, nor was it entirely the vacation. There are some other weird things going on, and I'm going to have to learn to deal with them or I'll never be able to write anything again.

First, my blog got really popular after Joel Spolsky linked to it. That guy is like the Oprah Winfrey of tech blogging. Yeah, I watch Oprah. I can't help it. When my wife's watching it, I try to ignore it as best I can. But then I sneak a peek, or I laugh at one of her jokes or one of her guests' jokes, and then I'm hooked until it's over. My wife Linh says Oprah is the most powerful woman in the U.S. Linh says that if Oprah told every woman in the United States to go jump off a cliff, they'd do it. Oprah, don't do it!

Well, if Joel told all the techies to go jump off a cliff, I'm sure only a handful of them would do it, probably just the parkour wannabes. But when he tells them all to go read my blog... well, I used to get a max of 8,000 to 9,000 hits a day. After Joel linked to me a couple of times, about 70,000 people came and peered at my blog, most of them newcomers.

After your blog gets that popular, even for a little while, you'd better grow a thick skin fast. I've seen people praise Joel and bash on Joel (more of the former, generally), and I've been able to read both sides with interest but without emotion. Just try doing the no-emotion thing when they're talking about YOU.

I mean 70,000 people is like a stadium-full. Imagine all of them glaring at you. Imagine them wanting to lynch you! Some of them did!

So I'd been planning to write an entry once a week, even a small one, and thanks to the Mystery Topic and Oprah-Joel and my work project and my vacation and whatnot, I haven't posted in over a month.

To help me overcome this block-thing, I'm just going to post small stuff for a while. It's the #1 rule of blogging, you know: when in doubt, spew it out. If you say something incredibly stupid and insensitive, no big deal, everyone will just despise you.

D'oh.

Well, we'll see how it goes. Maybe writing short articles will help. I have a whole bunch of things queued up that I'd like to write about. Maybe just writing about them will clear this whole blog-constipation problem up, and I can get back to pooping out entries with my usual, um, ah... my metaphor has stretched to the breaking point here... with my usual "aplomb". Ahem.

If that fails, I might just start writing under a pen name. Heck, my blogs would probably be a lot better for it, and more frequent to boot.

This is a hard problem. We'll see how it goes!

Senin, 14 Agustus 2006

Clothes for the Soul

I un-published this for a few days because I was so bummed that almost nobody appeared to understand any of the key ideas I'm trying to get across. I've lost sleep over it. Not only did people not understand the main points -- for instance, that notions of "race" and "gender" are going to be obsolete in 100 to 200 years, hence racism and sexism will be roughly equivalent to pants-ism and shirts-ism -- but they didn't understand the meta-point, either: that our current ideas about the world and about ourselves can make it horribly hard to contemplate new ones, technical or not. But I figure, screw it. My blog is already controversial; this won't make it any worse. Don't read this entry if you're a little squeamish. And next time I promise to be both funny and on-topic technically.



There's an idea that's gradually taking root in the United States. It'll take about another generation; that's how long this kind of idea takes to permeate. It's already much further along in many other countries, including Brazil, China and Korea, and others.

The idea is simple enough: your body is no longer a prison for your soul. It's become more like a house, one that you can decorate to your tastes. In the fullness of time it may even become more like clothes for your soul, and you'll change it daily.

It's interesting that this idea is having so much trouble in the US. That's not to say, of course, that the US is particularly progressive. We're behind most of the civilized world in cell phone infrastructure, and we never did manage to adopt the metric system (unless you define "adopt" as "shoot km/h signs down with high-powered rifles", in which case: adoption successful.) And we love sports in which an actual ball is in play for under 10 minutes in a 3-hour game. But Americans are as vain as anyone else, so it's strange that we haven't warmed to the idea of customizable bodies.

If you think idly about what the distant future will be like, assuming you don't take the apocalyptic view, then you might envision everyone in the future as being healthy, beautiful, and long-lived. That's the way it is in all the sci-fi movies: take your pick, from Logan's Run to Gattaca. It's not much of a mental leap, though, since from what we know of the Middle Ages, people were comparatively unhealthy, ugly, and short-lived. (By "ugly", I mean that people were more commonly disfigured from diseases or other misfortunes.) If you extrapolate a few hundred years into the future, it's easy to predict improved health and improved looks.

So we're in a strange limbo today, because making changes to your body isn't quite yet socially acceptable, but people assume that it will be acceptable in the future.

You probably think I'm overlooking the plastic surgery craze. Well then: if a 22-year old girl gets a nose job, and she has to wear a bandage for a couple weeks, does she tell everyone she got a nose job? Nope. She fell down some stairs, or maybe had a split septum. If people speculate that she got her nose redone, then she has to deny it, or say it was an accidental by-product of the surgery.

So yeah, there's a plastic surgery craze, sort of. But most people in the US (even in Southern California) aren't comfortable admitting it or talking about it. Instead they have to lie about it.

Let's take stock: what cosmetic changes are acceptable these days?

Tatoos and piercings have gradually become acceptable to everyone except the parents of the person in question. Plus it's hard to lie about them and say you accidentally shoved a steel bolt through your lip and then sat naked on an inverted permanent-ink design.

Anyone who's not going gray is allowed to color their hair pretty much any color they want without exciting much comment. A woman can color her hair to cover up gray. It's less acceptable for a man to do this, but he can more or less still get away with it. Wigs and toupes, however, can't be talked about openly: they're taboo.

Getting a wart or a mole removed: fine. In fact people will be mildly surprised if you don't go to the trouble to remove them. Getting a scar removed or hidden: also definitely OK. In fact, any and all kinds of reconstructive surgery to help recover from injuries or disease are perfectly acceptable, and you can talk about them without shame. Little blue pills, oddly enough, have to be taken in secret.

Getting your legs extended by a doctor who saws through your bones and adds metal extenders: that's one you don't advertise. The procedure is incredibly (and increasingly) popular in China, by all accounts. Heck, in the US you can't even tell people that you wear platform shoes.

Getting your teeth bleached: fine to talk about, though most people won't advertise it. Getting your anus bleached (a popular new procedure discussed to death by such luminaries as Howard Stern and Adam Corolla): not so much. You don't send before/after pictures around to your friends, to the best of my knowledge.

How about a boob job? Unlike nose jobs, breast implants are now more or less acceptable to talk about and, yes, even brag about. Everyone's getting them, and nobody seems to think it's a big deal any more. What about butt implants, which are super popular in Brazil? I don't know anyone in the US who brags about their butt implants, so I'm guessing no, that one's still taboo here.

Cosmetic vaginal surgery is all the rage these days, in case nobody's told you yet. You're practically the last person to find out. The two most popular variants are restoring the hymen, and removing the labia. You can bet your implanted butt that neither of those procedures gets a lot of coffee-table discussion with the relatives and co-workers. I think we can safely add them to the taboo list. Same goes for penile anything, with the possible exception of reduction on account of elephantiasis.

Eyelids: it's very popular in Asia to get your eyes "cut", referring to a procedure that introduces a fold in your upper eyelid, which allegedly looks nicer, albeit at the cost of no longer being able to close your eyes fully when you're asleep. My understanding is that you're not supposed to admit to having had this surgery.

However, changing your eye color via contacts is popular and non-taboo, so presumably if there were a surgical procedure to change the color permanently, it would also not be taboo. Lids, taboo. Color, not taboo. Lash extensions, taboo. Lasik, not taboo. Got it.

Liposuction: shouldn't admit to it. Artificial tanning: fine. Hair implants: don't admit to it. Veneers for your teeth: OK, for the most part. Lip implants: keep 'em secret.

And so on. There's a vast economy around cosmetics and cosmetic surgery, but only a handful of changes are socially acceptable in the US. By "acceptable", I mean they're things you'd talk about openly at work, like going to the dentist to get your teeth cleaned. For most procedures, even the most popular ones, you have to pretend you didn't do it.

In case you hadn't figured it out, I think the whole taboo-ness of cosmetic changes is pretty lame. I think the girl shouldn't have to say she fell down the stairs. People should be able to complement her on her pretty new nose the way you complement someone on a new haircut. Same goes for all the other procedures I've mentioned, although I confess even I might have trouble complimenting someone on their newly-bleached anus.

Generally speaking, though, I think it's pretty obvious to most rational people that the trend is towards having control over how you look, and there's nothing wrong with making yourself look better. If a change makes you happier, then it will almost certainly make the people around you happier too.

And for that matter, changes can make you healthier -- you can already get your eyesight upgraded and your teeth upgraded, so in some sense our bodies are becoming like so much hardware. What if you could get a new set of synthetic lungs, or a new heart, to put you in better shape and increase your life expectancy? It's an open question, since organ replacements aren't readily accessible, and they have to come from other people. But if you could grow them in vats, then would it be socially acceptable to purchase them for yourself? I sure hope so.

But futuristic upgrades aside, the fact remains: most permanent cosmetic modifications still too embarrassing to talk about openly. Why is that? And why is the US in particular so far behind many other countries in how open we are about discussing them?

I don't know. Maybe there isn't a simple answer. But my suspicion is that it's a byproduct of our puritanical heritage in the US. Cosmetic surgery is closely tied to vanity and pride, which are proscribed by any number of popular religions, presumably on the dubious grounds that if God made you ugly, then it was just "meant to be" and you have to live with it.

I'm not sure how many people actually think that way today in the US, in those exact terms -- probably no more than one percent of the population: a few million. But it was likely the majority opinion 100 to 200 years ago, and it takes a long time for a culture to shake off the often ridiculous ideas passed down from our forebears.

However, I also think that cosmetic surgery has the evolutionary advantage: beautiful people get better treatment in the world, whether the world is conscious of it or not. So being beautiful gets you, on average, better jobs, better pay, and a better lifestyle. It pays to be good looking. It seems like this is going to drive cosmetic surgery towards becoming more or less completely acceptable, up to and including changing your apparent race, roughly as fast as these things become technically feasible. Economics will drive it.

In the meantime, feel free to treat yourself. You deserve it. Don't let stupid, old-fashioned social mores (the same ones that keep the mall from being open late on Sunday, the one day when you actually have time to go shop) hold you back. And if you ask me, you shouldn't have to lie if someone asks you about your hair or your nose or your love handles or whatever you changed. Your body is your very own, and it's just clothes for your soul, nothing more. Decorate it however you please, and be proud of your decor.

Why did I write about this?


Believe it or not, today's rant was inspired by technical problems, which is why it's here in this mostly-technical blog. The technical problems (and I won't bore you with details) are the direct result of cultural problems related to the dissemination of ideas.

When you put two people together, they're smarter than one person. Ideas bounce around and settle in faster. A group of two acting in concert can learn faster and respond faster than a single person can: the whole is greater than the sum of the parts. But a group of three or four is back to being about as smart as a single person. A group of ten to twenty people acts about as smart as a lost child, and a group of fifty is only about as smart as a dog. It takes a while to teach a group of fifty people any new tricks. A group of a hundred people? A sheep, of course. A thousand or more? Lemmings. When we're in big groups, we just follow what everyone around us is doing. The bigger the group, the dumber we get.

Unfortunately, this means that getting radical new ideas across can be tricky. Imagine sitting in front of a sheep, trying to explain to it that new ideas have a hard time penetrating big groups of people, especially if they fly in the face of so-called conventional wisdom. I can tell you this much: the sheep will be unimpressed.

One of the many techno-cultural problems I've encountered is going to be the subject of my next blog. A lot of people are going to react very negatively to the ideas I present in this upcoming blog, and oddly enough, their reactions aren't really coming from them as individuals. The strongly negative reactions stem from membership in a group that thinks very differently about this technical subject than I do. But when you're in a group, even a virtual group comprised of people who subscribe to some technical belief, you're only as smart as a sheep. Happens to all of us.

I have various technical ideas in the oven that aren't ready to serve yet. They're in all stages of preparation, from still-mooing to raw to nearly ready to eat. In each case I'm looking for a way to break it to you easy, to explain it in just the right way.

That can be hard, because ideas embody change, and someone is always profiting from the status quo. The profiting isn't always money -- sometimes people simply have their self-image tied up in the status quo. If your idea threatens to change it, they feel you're threatening them directly.

Sometimes the time is just ripe for an idea, and everyone seems to have it at the same time. Other times, it's pretty clear where we're headed, but even so, people aren't willing to let go of some of their cherished old ideas that conflict with the new ones. That's where we're at (in the US, anyway) with plastic surgery. And sometimes an idea is so different and revolutionary that people either don't get it at all, or they're naturally inclined to misunderstand and criticize it. When that happens, you have to attack it from different angles, and try to use tricks like metaphor or analogy to help people make the connections you want them to make.

I think the plastic-surgery problem is well-positioned as a educational tool: it seems pretty obvious (to me, anyway) that a twenty-something girl with a bright future who's unhappy with her nose should be able to get the surgery without having to lie to everyone about falling down the stairs. You'd think everyone would be full of complements about her wonderful new nose, but instead we treat it like the Emperor's clothes. It's sad. And the situation won't change, not quickly enough at any rate, unless some sort of social miracle happens, in which trend-setters with charisma to spare start bragging about their new noses and lips and buttocks... who knows! Stranger things have happened.

Hopefully I've planted a seed with this non-technical article, one that will take root, grow, and flourish into a beautiful tree, which I can then yank a branch from and whack people over the heads with when they choose to resist ideas simply because they fear change.

If that doesn't work, and people still want to lynch me, well, I can always disguise myself with a fake moustache.

Kamis, 27 Juli 2006

Get Famous By Not Programming

Here at Whiny Blog Central, we frequently receive email from Alert Readers who tell us: "THANKYOUSOMUCH for you're latest blogg entry! Youve saved my BABY from becomeing an evil manager or a VIM user or whatever! Heres a personal check for $500!" And we can appreciate that sentiment, although we wish it would come from people who realize holding the check up to their screen so the email program can "see" it doesn't actually send anything to me. To us, I mean. We mean.

It is nice to hear that some people like what you write, though, since anyone who does anything noteworthy in the world will have critics, and criticism can really sting, even if you have a thick skin, or even a cephalothorax like some bloggers out there. But then, the critics are often critical because your writing stung them in some way, so I guess it's an eye for an eye in this writing gig.

Almost Famous

Earlier this week, my coworkers and I were astonished and more than a little amused to hear that I'm one of the ten most famous programmers in the world. Yup. That was the rumor, anyway. (Some versions of the rumor even had the number right.)

See, this guy named Jarosław "sztywny" Rzeszótko (he also goes by "Stiff", even though it clearly contains a vowel right there in the middle) sent me a nice email about six weeks back, saying, well... here's exactly what he said. You be the judge:

Hello!

I'm an 18-years old programmer wannabe from Poland and I run a blog in my native language. As an interesting (at least to me) experiment I'm trying to ask some questions I always wanted to ask the programmers I admire most, but never had the occasion to do that... The question and answers would be later translated, and published in Polish on the weblog. If You don't have time, find the question stupid, whatever - just answer a part of them, or simply throw out the email and forget that I bothered You. So, here we go:

(10 questions)


Because his mail was nice (not to mention flattering) and his questions looked interesting, and also (I think mostly) because he'd offered to translate it into Polish, it piqued my curiosity. So I told him I'd give it my best shot, and answered them.

Jarosław's idea was brilliant, of course, and I see a lot of people are kicking themselves for not having thought of it. Because who knows how much goodwill he used up from the seven other actually famous people who responded. There may not be another chance like that one for a long time.

But he didn't tell any of us who the other interviewees were, nor did he set any expectations around how much to write in response. In retrospect it's somewhat amazing that he got eight replies, but it's certainly no surprise that they varied so much in their tone and level of detail. We didn't know what to write, nor who we were writing for.

Seven famous people, plus me. Pretty cool interview.

So how did I get in there? I haven't done anything amazing.
Wyvern's pretty cool, but you probably wouldn't know, since (a) it's mostly young teenagers playing it, for the most part, and (b) I haven't published most of the source code, since I'm frankly embarrassed to have anyone see how bad it is. The game only works as well as it does because I spent seven years of my life on it, NOT because I'm a great programmer, or even an especially good one.

So I'm guessing Stiff didn't really choose me for my programming ability. What could it be, then? HMMMmmmmm... I'll give you two guesses.

Yup, you got it, on the first try I'll bet: it's because I'm a damn loudmouth. We're all using the same media here in BlogLand, but my volume is turned way up. "Blah, blah, BLAH," I'm known to yell semi-incoherently. BlaaaaAAAAAahhh!!! Gets their attention every time.

You know how after you watch a new X-men movie, you come out afterwards and ask whoever watched it with you which superpower they'd want if they could be an X-, ah, -person? You do ask, right? C'mon, you do. I know you do! Everyone does. Which superpower would you pick? Invisibility? Flying? Unstoppable momentum? Walking through walls? Telekinesis?

Well I'll bet you a dollar you'd never have picked 'Loudmouth Jerk'. But I guess beggars can't be choosers.

In any case, evidently due to my loudmouth superpowers, I got to be in the list, and my friends laughed at me a lot, and that was that. But it was fun.

Thanks for including me, Jarosław!

Famous programming heroes

Do you have any programming heroes? I do! Oddly enough, though, I've never really seen much of their code. Most of the famous-ish programmers I respect have actually made their impact on me through writing, and it's usually just prose, with maybe a little code interspersed.

There are programmers I admire who've built things that I use a lot. But when I try to come up with a list of programmers I admire (and I specifically mean people I don't know personally), I find they almost always fall into one (or both) of just two categories:
  1. People who wrote a useful programming language, an operating system, or an especially important framework.

  2. People who wrote a really neat book about programming.

Any sufficiently flexible and programmable environment — say Emacs, or Ruby on Rails, or Firefox, or even my game Wyvern — begins to take on characteristics of both language and operating system as it grows. So I'm lumping together a big class of programs that have similar characteristics. I guess you could call them frameworks, or extensible systems.

I've developed a personal distaste for the word "framework" because it's used to describe so many technologies that are unbelievably cumbersome and overspecialized. You know which ones I mean. But realistically, framework might be the best word for the kind of system I'm talking about. Unlike libraries, frameworks are hard to learn and hard to reuse, so for any given framework you probably love it or hate it.

If someone builds a library that I find useful, I might notice their name, but I'm not likely to remember it or think of it when I think of great programmers. Ditto for most applications or utilities, even highly useful ones. I'm thankful, sure, but that's a far cry from eternally grateful.

But when someone builds a framework — any environment that we live in and actually enjoy programming in — and there's one person who's chiefly identifiable as the primary author of that framework, then I think we tend to admire that person, and unlike other programmers, the person starts to become famous.

Even if they're a crappy programmer.

Not that we'd really know, because how often do we go look at the source code for the frameworks we use? How much time have you spent examining the source code of your favorite programming language's compiler, interpreter or VM? And by the time such systems reach sufficient size and usefulness, how much of that code was actually penned by the original author?

Sure, we might go look at framework code sometimes. But it just looks like, well, code. There's usually nothing particularly famous-looking or even glamorous about it. Go look at the source code for Emacs or Rails or Python or Firefox, and it's just a big ball of code. In fact, often as not it's a big hairy ball, and the original author is focused on refactoring or even rewriting big sections of it.

I suppose an individual who manages to get a big system built and marketed and adopted by lots of people can't really be a crappy programmer, by definition. Some people (e.g. Richard Gabriel) have argued convincingly that writing crappy code has evolutionary advantages. I know it's easy to despise someone who's written obviously ugly, unmaintainable code. But our industry is still figuring out how to do software engineering properly, and a lot of very important code was written before modern software engineering ideas were widely disseminated.

And even then, sometimes the schedule just gets you. Given a choice between having significant impact by getting something out the door, and spending a bunch of time up front writing every line of code to be beautiful and high-performing and robust, which would you pick?

I'll pick impact. You can always fix the code later.

I know on my last project (at work), I wrote a lot of quick and dirty code. I mean, it's not terrible, not the kind of code that you'd fire someone for. We have coding conventions that I adhere to, and I tend to organize and document and refactor my code pretty conscientiously as I go, out of habit. But it's been this incredible six-month race to the finish, and I've made a lot of decisions out of expedience that I knew I'd have to revisit later, stuff I wouldn't exactly be proud to show off.

Anyone who looked at my real-life code, without knowing anything else about me, would probably conclude that I'm an ordinary programmer. And I'd guess that if you looked at random chunks of code from your favorite framework, written by your favorite programmer, you'd conclude that it had been written by mortals.

So what makes a programmer famous? Apparently not programming! Or at least not their actual code.

You can try the experiment yourself. I'm actually curious. Go through the list of programmers you admire most (people you don't know personally), and decide why you admire each of them.

I think you'll find the same thing I did: each person either wrote a framework you like, or they write about technical topics really well (or at least in a way that keeps you coming back for more.)

Get Rich By Not Programming, Too

Can programming make you rich? Well, let's figure it out: think of all the fantastically rich programmers you know. Not a very long list, is it? And did they get rich by virtue of being incredible programmers?

Tough question! In practice, virtually all the wealthy programmers you know (or even know of) got rich via startups. They were early employees at a company that became phenomenally successful, either through a public IPO or through a high-dollar acquisition.

Were these early-bird programmers great, or just lucky? It's not easy to separate the two, because their quality as programmers (however you choose to measure that) probably had at least some direct impact on the company's ultimate success. But some may have been average (or even bad) programmers who wound up in the right place at the right time. I know I've seen it happen. And some successful programmer-entrepreneurs might attribute their financial success to (their own) great programming ability, when it may be wholly due to their keen business acumen, or to their great decision-making and execution skills.

Most programmers aren't rich. It's a good job, no question, and it pays pretty well in most places. But most programmers are a far cry from "wealthy". Is it even possible to get rich by programming?

Sure, if you take a risky pay cut, and you pick the right product or service, and you bust your ass like nobody's business for at least 12 to 18 months, and you do a great job of marketing your product, and you find a buyer, and you do a great job of negotiating, and you get a little lucky. If all those things happen, you can get rich as a programmer.

But we didn't list "be a great programmer" or "write great code" in there anywhere, did we? They may not be essential ingredients. If your code just barely works, then it's good enough. A startup that manages to get acquired doesn't have to have had great code; they simply had to either establish a lead in a new market, or put on a damn good road show.

If not rich or famous, then what?

I've spent a lot of time thinking about improving my productivity, and advocating in my blogs that engineers should work to improve their own productivity, skill set, and knowledge base.

But what do those things really get me? Apparently it's not going to make me rich -- certainly not on its own, anyway. And it's not going to make me famous: a small amount of code (something that thousands of people could look at) isn't going to be impressive, and a large amount of code won't be digestible.

So why bother getting better?

Well, there's personal satisfaction, I guess. It does feel nice to be able to crank through stuff quickly. It feels related to why I prefer biking to running -- the scenery changes faster. But if you're more the type who likes to sit on a bench and admire static scenery, then staring at the same function for six days might be more rewarding for you.

And personal satisfaction just blows compared to being filthy rich. Right? Well, they do say money can't buy happiness, but every time someone's tried to buy me some happiness by giving me money, it's worked on the first try. Never fails, in fact. So I think "they" may be full of it.

I love programming, don't get me wrong. But I'd love it even more if I were a fat old dragon sitting on a big pile of gold, because then I could buy a zillion-inch monitor and work on programs I like, rather than the (only occasionally intersecting) set of programs that my boss tells me to work on.

In the meantime, I keep working on improving my skill set, on the off chance that my skills will actually matter, should the ideal startup scenario ever present itself. And it feels nice to learn new stuff, at least after you've gone through the pain of learning it.

Until then, all I really have of my own is my Mouth of Great Volume, which I'll keep on applying in my blogs so I can continue to reap the benefits of being mistaken for someone famous.

BlaaaaAAAAAahhh!!!

Sabtu, 01 Juli 2006

Wizard School

It's hard to believe it's only been eleven years since they opened the first Wizard School. I hear they just opened new campuses in Singapore and Istanbul. That's, what, sixteen or seventeen locations now? And enrollment is already backlogged five to ten years at the new campuses. The money involved just defies the imagination. Mine, anyway.

In retrospect it seems pretty obvious. Who'd have guessed they'd make so much money, though? We were all there, all programming in the same industry, but somehow the two founders saw an opportunity there that the rest of us missed.

I think it's worse than that, actually. I mean, I thought it was a joke when I first heard about it. Didn't you? But I'm such a late adopter. I didn't know about Napster, not really, not until they were being shut down. I didn't buy a DVD player or a CD player or an iPod until they'd been out at least six or seven years each. Stuff like this always feels like it happened overnight, but I guess they've been building to it for a quite a while.

I mean I'd heard about the Wizard Academies, sure. But it was this subculture, this thing interns and high school kids were buzzing about, should they go to college or wiz school, blah blah blah. I wasn't really paying attention. Then suddenly it was this mega-phenomenon, growing faster any educational institution in history.

It's not just that we didn't think of it. Face it: we would have scoffed if someone had suggested the idea. C'mon... "Wizards"? It sounded like someone was just jealous of J.K. Rowling. Especially the more you hear about the campuses.

Some people have been mailing me lately, random people asking me if their kids should go. It's expensive. Way expensive. Tough choice to make, even now, with Wizard Academy grads making anywhere from a quarter million to a million a year, while the rest of us plod away in 5-figure territory. I'm not exactly going to make that decision for them, but I threw together some notes — most of it old hat for anyone who hasn't been living under a rock — to help them make their decision.

I'm dumping my notes here until I think of a better place to put them. For now, I can just forward this stuff to anyone else who asks.

None of it should be new to you.

Why Not College?


It's still an honorable thing to get a Ph.D. I think that'll hold true for another twenty years, at least, because people like to hold on to their traditions. And even an undergrad degree in CS can still get you a job. If you can't afford the Wizard Academy, or you can't pass the entrance tests, or you just got on the waiting list too late, then a CS degree from a good university is still probably the best way to prep for a job in the tech industry. It's not as if the Wiz Schools have killed CS at universities. Not yet, anyway.

Besides, CS degrees are changing now. A lot of the more progressive universities have been overhauling their CS curricula as fast as they can, in response to the Wiz Schools. I mean, my God. The Wizards are coming in with significantly higher computer science scores than the CS grads, and theory isn't really what the Wizards are known for.

Heck, the wiz schools themselves are the newest fad in research departments (sociology and education departments, mostly) across the country — all over the world, even. Everyone has different hypotheses as to why Wizards are so damn good. Nobody seems to know for sure. But they are good, that much at least is indisputable. And they're in unbelievable demand now.

You hire a Ph.D., it's hit-or-miss. Some of them are brilliant. But then some subset of virtually every educated group is brilliant. The problem is that the notion of a Ph.D. has gradually been watered down for the last century. It used to mean something to be a Doctor of Philosophy: it meant you had materially advanced your discipline for everyone. Von Neumann, Nash, Turing — people like that, with world-changing dissertations, they just don't happen that often anymore, at least not in CS. Well, they probably occur at the same frequency, but it's one in a thousand at best.

Instead, what usually happens is a bright young Ph.D.-to-be chooses a school based on expedience: finances, or location, or parental pressure. There might be a dozen or so advisors to choose from, and the department as a whole has only one or two really big, prestigious areas of focus, areas for which the school is known (and hence funded). So if a kid goes to a school that does a lot of X, chances are pretty damn good the kid's going to do her Ph.D. thesis in X. But it's probably specialized to death, and the kid will wind up working for years on some tiny slice of almost-nothing: little prototype mobile doodads that track forest monkeys or something. And the kid will lose faith, stop hoping their thesis will ever mean anything, and they'll go through the motions until their advisor pities them and lets them defend.

I'm not saying it's a rubber stamp. These kids have to work hard for their Ph.D., and a lot of them never quite finish. But too often they finish without having written more than a few hundred lines of code in the past five years. Or they've over-specialized to the point where they now think Big-O is a tire company; they have no idea how computers or computation actually work anymore. They can tell you just about everything there is to know about SVM kernels and neural-net back propagation, or about photorealistic radiosity algorithms that make your apartment look fake by comparison. But if you want a website thrown together, or a scalable service written, or for that matter a graphics or machine-learning system, you're usually better off hiring a high-school kid, because the kid might actually know how to program. Some Ph.D.s can, but how many of them is it, really? From an industry perspective, an alarming number of them are no-ops.

The bigger, better-known companies — Yahoo!, Google, Amazon.com, Microsoft — those guys can spot a dud a mile off, over the phone even. Credentials don't matter, not strictly even for Wiz Academy grads with eight OWLs and five NEWTs or whatever the hell they're called. (I still can't believe how closely they copied Rowling's design.) What matters is what you know, and what you can do, and a Ph.D. laureate in CS these days, even from a "top" university, has about an 80% chance of failing interviews at one of these companies.

It's still honorable to get a Ph.D. But it's no guarantee of a job. Not a high-paying one, anyway, not at a company with a bright future. It is a lot cheaper than Wiz School, though, and it's easier to get in. So I'd consider it a pretty good fallback option.

Wiz School Tour


Well, you know all about the campuses; you can't watch the news for two hours nowadays without getting some sort of virtual tour, or hearing about some company's stock soaring after they won the first-round draft picks from the Nassau campus, or Kauai, or Chardonnay. They're half Google and half Hogwarts, seven-year boarding schools complete with Great Houses, robes, the whole works. Wizard Schools. Just like you'd expect, I guess.

They're always located out in remote, beautiful areas. No expenses spared. Full-time staff, like you'd find in a hotel or a cruise ship. Rich kids and scholarship kids alike, but only the brightest. Reminds me of Ender Wiggin's Battle School. Not just anyone gets to go. You've got to be a prodigy, a kid genius, and not just at math or science. They look for kids with spark, with personality, and their interviews are famous for being both gruelling and quirky. Interviews can last for up to 2 weeks. There's no guesswork involved; they keep you there until they know everything about you, or at least enough to know if you're Wizard material.

Just getting invited to the interviews is a big deal, something to brag about; being selected probably qualifies you for any early-entrance program at any school in most countries. Only 20% make it to the third day, and only one in fifty interviewees gets an offer to attend the school.

I hear they're giving more and more scholarships now. At first it was all rich foreign kids: kids whose parents couldn't get visas, due to the stupid U.S. immigration regulations at the time, which were later relaxed after the big Brain Drain hit. That's another story, of course, and one you already know about. But it explains why there were so many kids from countries like Indonesia and Thailand and Hong Kong in the first graduating classes: insanely brilliant kids from rich families who wanted the best education money could buy, and who were willing to take risks and be early adopters for what even today sounds like the craziest stunt (or scam) ever pulled.

It wasn't crazy, though, and it was no scam. Those first kids that graduated, seven years later, all of 18 years old, they're the youngest crop of CTOs and senior architects and company founders our industry had ever seen, and maybe that any industry had seen since, I don't know, the Gold Rush. Wiz Kids. A well-deserved pun.

Are They Really Better?


Oh, man. You have no idea. A fifth-round draft pick (companies bid for draft picks, of course; you can't just hire any Wizard Academy grad you want, and the process is now independently regulated to ensure fairness) comes "stock" with a skills lineup that would make any hiring manager drool uncontrollably. Probably with fear, since a kid like that will obsolete anyone with the title "hiring manager".

They type 140 to 160 words a minute, almost soundlessly, and always bring their own keyboards. They disdain mice, although recently I hear they've been using pointers attached to their foreheads. No idea how they control them so easily — makes my neck hurt just to think about it. Lots of practice. Hours of drills. Start 'em young, and they all say it's a snap, just like you'd tell your grandmother that using a mouse is a snap, when it's pretty obvious it really isn't.

They know their discrete mathematics and CS theory cold, of course, although I hear it's at the expense of more traditional disciplines like trigonometry and physics, unless they choose those subjects as electives. They're in class for 8 to 10 hours a day, and their homework load is at least equivalent to a full-time college degree, but they're starting it all at 11 or 12 years old.

But all that aside, they're probably most famous for their coding. Just plain, basic coding. I mean, we all think of ourselves as good coders, but the Wizards do it as easily as we breathe air. While a "normal" programmer is puzzling over design patterns, or trying to simplify complex code paths, a Wizard is blasting out code at the rate of hundreds of thousands of lines a year. And it's all amazingly high quality. Numerous studies have shown their code, on average, to have 80% fewer bugs and at least 100% (2x) better performance than the industry average. It's safe to say the Wizards graduating at the bottom of their class are still safely in the top 1% of industry grads.

Of course, blasting out hundreds of thousands of lines a year is missing the point. If a Wizard is given complete technical control over a project (which is usually the smartest thing to do, but companies are rarely very smart), the Wizard will typically write in one of the super-succinct "folding languages" they've developed on campus, usually a Lisp or Haskell derivative.

They call them Folding Languages because they write code that writes code that writes code... Wizards swear by it, and there's no question that they can produce amazingly compact, fast, clean-looking code. But 90% of the devs out there claim they can't read it, and whine a lot about it to their bosses. Given that most companies can only afford a few Staff Wizards, the Wizards are usually forced to capitulate and use Java or C++. They're equally comfortable in any language you throw at them, though, and if you force them to use a verbose language, well, you get what you ask for. It still amazes me that companies are bragging about how many lines of code their Wizards have produced. Potential startups take note: your competitors are usually idiots.

Will My Kid Be Normal?


Good question. It's not exactly "normal" to be a millionaire by age 22. But if you're worried that your kid is going off to join some strange Scientology-like cult, just go visit the campus. Online, of course. You can't actually get onto one of the campuses unless you're press, family, police, a guest speaker, or a Personage of Note like, say, the President of some country. They don't want you bothering the students. But you can take online tours, and they're all quite amazing, using technology largely developed at the campuses themselves. And it's pretty much what you'd expect: a carefully monitored boarding school. The robes and Wizard stuff is mostly there to make it fun, and to imbue it all with a sense of seriousness that always comes of wearing uniforms.

The professors are uniformly entertaining and brilliant. They're always seasoned industry pros, usually famous names. Everyone knows Larry Wall as the Head Wizard of the Aspen campus, the first campus they opened on U.S. soil. Most young folks don't realize Larry was the inventor of a language called "Perl" that was really popular in the 1990s and 2000s, up through 2010 or so. He was independently famous in his own right before taking the job, but these days he's famous entirely because of the Headmaster gig. He's won the Dumbledore Award for three consecutive years, so he's obviously popular with Wiz Academy students worldwide. And I hear Jamie Zawinski just left his S.F. club to take the second-in-command and Tools Master position in the Christchurch campus. Wanna be a prof at Wizard School? Gotta be famous, funny, proven, brilliant, and seriously committed to the students' success.

The kids do more physical education and activity than at most other schools. No, it's not Quidditch — that would be a neat trick — but they have soccer and golf and archery and horseback riding, and they're graded on physical fitness and physical dexterity. They also have to learn a musical instrument and a significant amount of music theory, as the schools claim it makes them better programmers and designers. They all do tons of electives in the arts and sciences. And they all come out fluent in at least 3 languages (one of which must be English) chosen from a list of nearly 100 possibilities. The students are pretty well-rounded by just about any objective standard.

In addition to their math, computer science, and unrivaled coding skills, Wiz Academy grads all seem to know how to draw. At least I've never known one who couldn't. They're not all great artists, of course, but they all receive a substantial amount of training as artists, and seven years of practice at anything, even part-time, can really add up. This puts them at a natural advantage when they're creating UIs and documentation, since they rarely need to wait around for a UI designer. Or at least they can whip up a sketch that a full-time designer or artist can use as starting material. The rest of us programmers have to pantomime what we want until the artist finally draws something that looks like what we (vaguely) had in mind. I'd never have guessed basic drawing skills would be so useful, but now that I see Wizards using them all the time, I've had to change my mind about it. I think we all have.

All the Wizards I've ever met personally have seemed nice enough. I'm sure you can find a few who are arrogant jerks, but you can find people like that anywhere and everywhere if you look hard enough. Most Wizards I've known have been ordinary, nice people. Sort of like Olympians, or Cirque du Soleil performers, or any other elite group of people who've trained since childhood to do what they're doing as adults. They're just people, and a lot of their personality is probably a function of how well you raise them before sending them off to boarding school.

So yeah, I'd say they're pretty normal. I sure wish I'd gone to Wizard School.

What's Next for Wizards Worldwide?


Wizard Schools are the darlings of the press. Who knows how long it'll last. The idea that started as a half-joking blog entry in 2006 has rapidly turned into the biggest phenomenon of the past decade, with no end in site. It's possible that Wizard Schools could eventually obsolete "regular" schools, with lower-end competitors (Fairy School? Somehow I doubt it...) stepping in to siphon off unmet demand.

It's equally possible that traditional schools will continue to borrow ideas from the Wizard Schools, in much the way that big companies circa 2006 started copying Google's philosophy of massages, free food, and other amazing perks in order to attract and retain top talent. That stuff was innovative back then, but it's fairly commonplace nowadays. Once Google had proved it worked better than frugality, everyone else had to follow suit: economics demanded it. Everyone who didn't got the second-best (or more commonly, the nth-best) employees.

One thing is clear: regardless of whether you think the Rowling-style environment is strictly necessary for producing Wizard-quality grads, the enrollment backlogs have shown that there's a huge, worldwide craving for improvement. People were only going to college because there was nothing better out there. But universities aren't really there to produce superstar programmers; their primary job is research, not education, and at least until recently they hardly focused on the students at all. Some profs even considered it beneath them to teach undergrads; it's no wonder so many CS students were graduating without knowing the fundamentals of their discipline: compilers, operating systems, algorithms, computation theory, and other key areas. Let alone Unix, the Web, and the tools of the trade.

Now that the Wizard Schools have proved the market exists, it's hard to imagine that competitors won't appear. Right now it's hard to get first-rate professors, since of course they all want to go off and teach at the existing Wizard Academies. But with a suitable thematic marketing twist, or a sizeable investment from a charitable billionaire, just about anyone could become the next hot education destination.

I'll tell you this much: I'm sending my kids, if they can make it in. In fact, maybe I should start a Wiz Academy Prep School... I'd better not tell anyone about this; it sounds like an idea worth going after. Yeah... I'd better look into it. There are an awful lot of people in this world who care about improving their skills and knowledge, and they want to do it as fast as humanly possible.

I wish I'd thought of it back in 2006. I guess we all do.

Sabtu, 10 Juni 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!