People are subject to trifling likes and dislikes every day. There seems to be no end to the division and subdivision of taste. In India, in those days, if I wanted ice cream after a meal, I simply ordered ice cream. At most there might have been two or three flavors; often there was only one. Today I have one hundred and forty-seven varieties to choose from, and it’s not enough to want chocolate; I have to decide between possibilities like Dutch, Bittersweet, Super Fudge Wonder, and Chewy White Chocolate Macadamia. (Often I just tell the clerk, “Give me the one you like best.”) And for coffee I have to specify French Roast, Colombian, Kona, or one of a dozen other varieties. I know people whose whole day is affected when they can’t get the coffee they like, made just the way they like it. As our preferences get fractioned finer and finer like this, the range of what we can tolerate narrows to a slit—in everything, because this is a habit of the mind.
About Jamis
He makes marshmallows and bow ties, plays guitar, and researches dead people. Sometimes all at the same time.
Models vs. Modules
When an application grows organically it accrues features like a snowball rolling down a dirty hill. With a little careful engineering, this works great (since the snowball is actually quite willing to be guided) but sometimes you need to stop and rethink things, do a little refactoring. We’ve done this (many times) with all of our products.
Most recently, I’ve been working on some cleanups and optimizations to the person avatar and company logo code in Basecamp. The evolutionary snowball (for the avatar feature, at least) progressed something like this:
- In the beginning, there were no people avatars.
- Then one day, we added the feature. This introduced methods on the Person model like
avatar?
andavatar_path
andattach_avatar
. There were something like seven new methods that were added to Person as a result of this. - Some time later, David went and cleaned it up, moving those new methods to their own module. This was great, as it kept the definition of the Person model clean, and kept the avatar-related code separate.
This brings us to today. The code remains really clean, overall, because we’ve continued to follow the pattern of moving related methods into modules, and just including those modules in the base model.
Continued…Remember the strop
Last night I made some time to do some wood carving. I haven’t had much opportunity to carve anything since October, and I’ve missed it. There’s something supremely meditative about it: just you, a few blades, and a block of wood.
Good tools definitely help, so last year I invested in some nice gouges. They’re really sharp, well balanced, and just very comfortable to hold for long periods of time. The “really sharp” bit is probably the most important though; it’s remarkable how easily a truly sharp blade can cut through wood. With just a tiny bit of pressure, the gouge hisses softly through the wood, and the shavings curl up over the blade like little pillbugs playing dead.
Sometimes, though, I’ll hit a tougher part of the wood, where the grain is thicker or less even. Or I’ll need to cut across the grain, which requires a little (but not much) more force to do. So I push a little harder, and with a soft whisk the blade does its magic just as before. Push, whisk, push, whisk, push whisk... Hypnotic, almost. Very meditative.
Because I’m always adapting, almost unconsciously, to the different grain directions and densities, it’s so easy to forget how easily the blade cut through the wood when it was newly sharpened. I find myself thinking, “it’s still plenty sharp, I’ll go a few more minutes and then hone it.” Always just a few more minutes. One more cut. Just need to finish this one section…
When I finally sit down and run the blade over the strop, it only takes a few passes to hone it. Four or five trips down the leather, maybe about thirty seconds total away from the project. But what an amazing difference it makes. Those four or five runs across the strop are enough to bring the blade back to its original keenness, and it never fails to amaze me how easily the blade cuts through the wood, compared to just before stropping. I thought the blade was plenty sharp before. I had forgotten just how sharp it could be, and what a difference that makes.
Now, let’s jump back four years. Four years ago (almost exactly! January 27th, 2005, in fact) Jason and David invited me to come to the Building of Basecamp workshop in Seattle. I was working for BYU at the time, but Jason and David were doing their best to show me a better way.
I was comfortable at BYU. I had responsibility. I was involved in technology decisions. I was capable. I was able to push through the fibers of my career without too much trouble, I thought.
But then I attended Building of Basecamp. It was relatively short—a few hours in a room, listening to Jason and David talk about Getting Real. What they had to say was simple, to which anyone who has ever attended a Building of Basecamp or Getting Real workshop can attest. It was, for me, a few brief passes over the strop. I came out the other side sharper, renewed. I wasn’t satisfied to be merely a career programmer; I remembered the passion and delight I originally had in writing software.
(It was just a month later that I quit my job at BYU and started working at 37signals.)
This concept is not new. (Stephen Covey talks about it in his Seven Habits book, where he calls it “sharpening the saw”.) But it’s still valuable. All too often we can get stuck in a rut, thinking the resistance we feel to life or career is normal, forgetting the thrill we felt when the blade was new. All it takes is a moment to step back and remember the strop; the time spent will more than pay for itself in the long run.
A better way to learn grammar
Learning grammar has to be one of the most boring parts of studying language, especially studying the grammar of your native tongue. There are always exceptions of course—perhaps grammar is your cup of tea—but I’d bet it’s safe to say that most of us would rather undergo a root canal than sit through a lecture on inflectional morphology or modal forms.
However, when my wife was in college, studying linguistics, a classmate of hers had a really fascinating senior project. He proposed (and in fact, implemented) a sixth-grade grammar curriculum with an interesting focus: he had the kids create their own conlangs, and introduced both grammar and orthography concepts as part of that process. He supported the curriculum by showing the kids interesting real life examples, including (among other things) Mayan heiroglyphics!
I wish wish wish wish WISH that I’d had that man as my English teacher when I was in school. What a fascinating way to present an otherwise dry topic. Practical applications trump contrived examples every time.
Also, if you happen to be into conlangs, you may be interested in the 3rd Language Creation Conference, to be held on March 21 and 22 in Providence, Rhode Island. Whether you want to present or just attend, it looks like opportunities are available. (Disclaimer: I’m not affiliated with the conference, but it’s being organized by a friend of mine.)
A whale of a tale
I visited with a neighbor this weekend. He’s my parents’ age (which is to say, middle-aged), and is the undisputed king of the tangential story. Given any question, he’ll manage to turn it into a 5-10 minute yarn. This would be annoying, if it weren’t for the fact that he’s got some awesome stories.
This weekend I asked him for the correct pronunciation of his last name, which is rather unique. In one sentence, he answered my question, and then proceeded to relate the following story.
Continued…When hi-tech is too-much-tech
Is anyone else annoyed by the “just speak your choice” automation in so many telephone menus? I feel like an idiot mumbling “YES!” or “CHECK BALANCE!” into my phone. Maybe it’s the misanthrope in me coming to the front, but I’d much rather push buttons than talk to a pretend person.
What problem does the “speak your choice” technology solve? Is it just to work around the limitation of rotary phones not working with the other menus? (Does anyone even use rotary phones anymore?) It feels, to me, like an example of “we do it, because we can” syndrome. Sometimes, lower-tech really is sufficient-tech.
Stop pretending
I’ve recently recognized a nasty coding habit I seem to be developing. It’s been developing for a few months now, and while I kick myself every time I discover myself doing it, the habit itself is remarkably hard to kick.
I’ve been working on enhancing our internal Queen Bee application, this time making it so we can more easily track the performance of our Job and Gig boards. The change itself is pretty straightforward, but I found that when it came time to build the actual UI, I got stuck.
I kept chasing my tail. I’d look at the existing reporting UI that we have for our other products, and then I’d start thinking what needed to change to adapt it for the Jobs/Gigs reports. That would then lead me to think about potential refactorings in the code needed to support the (hypothetical) UI changes. Thinking about the code refactorings would lead me back to the UI, where I would think some more about the visual impact of the code refactorings, and so I would go, loop after loop, ad nauseam.
It’s ironic that, even after nearly 4 years of drinking the Getting Real message almost every day, I’d get stuck in such a trap, because the solution really is to just stop pretending and make something. In my case, I had to sit down and just mock up the page, throw together some HTML with fake data in it, and see what it looked like. And it turned out that I didn’t need to change the existing UI or code much at all—the new stuff was actually independent enough that it stood almost completely on its own. Oh, the bitter, bitter irony! I had wasted almost two days worrying about a non-issue.
So, if you ever catch yourself playing mind games with your code, just stop and make something. Pretending is poison. Stop drinking it!
Etymology: One
Etymology is fascinating to me. Most recently I was reading about the history of the word “one”. Have you ever wondered why it’s pronounced wun instead of rhyming with own? According to the sources I’ve read (including the awesome Online Etymology Dictionary), it originally did. In fact, the word only still uses that pronunciation, and derives from the same root. The change apparently began in the 14th century in southwestern England, and by the 18th century it was in common usage.
Related: did you know that the term “one night stand” was originally used in reference to theater performance? It wasn’t until the 1960’s that it was first used in a sexual sense. Also, “one-of-a-kind” was first used in the 1960’s as well. On the other hand, “one fell swoop” was first used by Shakespeare, in Macbeth.
Unconferences?
I just got back from RubyConf 2008, in Orlando, Florida. It was really a fantastic conference. It came off really well, and everything was top-notch. What I loved most was reconnecting with the community, just sitting, chatting and hacking with people from all over the world with whom I normally interact only online.
It made me realize that what I really want to attend is an “unconference”, where people pay to come and listen to one (or maybe two) keynotes by prominent community members, but then the rest of the time is spent in unstructured hacking sessions, where people cluster and work together on any number of different projects. If people want to stand up at a mic and talk about something that interests them, that’s fine, but the focus would not be on presentation, but on working on interesting projects.
Barcamp sounds kind of like this, but the emphasis still seems to be on presentations. Has anyone ever attended something like this?
CachedExternals: managing application dependencies
We’ve been slowly trickling some of our internal projects onto GitHub, making them more widely available in the hopes that (for one) they’ll be as useful to others as they are to ourselves, and (for another) that people will contribute patches back to make the projects even better.
Today I moved our CachedExternals plugin there. You can read all about it in the README, but read on for an overview (and justification).
Continued…