this is totally gonna work… » Software

You Put Merb In My Jetty!

February 11th, 2009

In the latest update of The Chronicles of Stuff Alex Figures out at Work, our intrepid hero figures out how to run Merb inside an embedded Jetty instance!

Now you may ask yourself, “for the love of God, why would you want to do something like this?” Well, at work we do a lot of internal web services. For my particular team, we’ve found a real sweet-spot by using an embedded Jetty server sitting right next to a BDB instance. There are no extra processes or packages to manage (e.g. apache or a RDBMS). However we were becoming dissatisfied with our current web layer which is a homegrown REST framework that sits on top of the Servlet API. So in a fit of rage, I decided to see if I could stuff Merb in the middle of this mess.

You may also be asking yourself, “why not use the jruby-rack gem directly?” The answer is that the jruby-rack gem makes a lot of assumptions about how you want to run your application. First it assumes that you’re cool with packaging things up as a WAR (which I’m not) and, secondly, that your application is primarily a Rails/Merb application. In my case, for better or worse, our app is really a BDB application with a Merb app glommed onto the side for web visibility.

The Solution

I can’t take complete credit for this solution. If I hadn’t found Jan Berkel’s post on putting Rails in Jetty I would have never figured out how to stuff Merb in there. To give yourself some context, take a look at that post first. Then take a look at the “Merb-ified” version of the same recipe below. Both solutions assume that you’re configuring Jetty within JRuby.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server = org.mortbay.jetty.Server.new
thread_pool = org.mortbay.thread.QueuedThreadPool.new
thread_pool.min_threads  = 5  # adjust as needed
thread_pool.max_threads  = 50
server.set_thread_pool(thread_pool)
context = Context.new(nil, "/", Context::NO_SESSIONS)
context.add_filter("org.jruby.rack.RackFilter", "/*", Handler::DEFAULT)
context.set_resource_base(Environment.resolve)
context.add_event_listener(MerbServletContextListener.new)
context.set_init_params(java.util.HashMap.new('merb.root'=>; Environment.resolve,
    'merb.environment' => 'production',
    'public.root' => Environment.resolve('public'),
    'gem.path' => Environment.resolve('gems'),
    'org.mortbay.jetty.servlet.Default.relativeResourceBase' => '/public',
    'jruby.max.runtimes' => '1'))
context.add_servlet(ServletHolder.new(DefaultServlet.new), "/")
server.set_handler(context)
server.start

Tweaking

At first blush our performance seemed to be pretty lacking. This required two tweaks: putting Merb in “production” mode and dealing with poor I/O due to logging. In the previous snippet you will notice that we set the merb.environment to production. Yes we lose the quick dev turnaround, but since there is a lot of Java in this project we usually have to recompile anyway which requires a restart anyway (phooey).

As for the I/O issue, a little digging revealed that shutting up Merb as much as possible would help reduce the amount of JRuby-level IO. In our config/init.rb we configure logging like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
Merb::Config.use { |c|
c[:environment]         = 'production',
c[:framework]           = {},
c[:log_level]           = :warn,
c[:log_file]            = Merb.root / "logs" / "merb.log",
c[:use_mutex]           = false,
c[:session_store]       = 'cookie',
c[:session_id_key]      = '_facet-store_session_id',
c[:session_secret_key]  = '49411912879b879e13f89a9280c0f6aaa2e3ab58',
c[:exception_details]   = true,
c[:reload_classes]      = false,
c[:reload_templates]    = false
}

Here we set the environment to “production” again (yes, you need to do both). Also we upped the log level to “warn” which significantly reduced the amount of logging merb does. With these tweaks in place we found that the Merb port of our service was operating within about 80% of the level of performance we were getting from our pure-Java solution.

Benchmarking was done by running httperf tests against the resources we expose and comparing both the number of requests per second and the average response time. Given that the options for generating XML, HTML and JSON were all so much easier than what we were doing in the servlet version, we were willing to live with the performance hit.

Rewriting History with Git

January 31st, 2009

This past week I spent some quality time with git’s history-rewriting capabilities. Over the past few weeks I had been working on a rather long-lived branch full of JRuby and Merb patches. Some of the fixes and changes were ready to go in the next release, others were still a wee bit experimental and so my plan was to split the patches in two. The ones that were ready would get pushed upstream while the not-ready-for-primetime stuff stayed on a local branch.

That seemed like a great plan until I realized just how tangled some of the patches were. It isn’t difficult for this to happen. As you extend the functionality of a system, you often refine earlier work. This was especially true in my case since we were introducing JRuby to a previously Java-only project and so there was a lot of experimentation and refinement. What I was really trying to do was re-write my commit history to separate the changes. Small cleanup commits could be collapsed with others to make the entire commit-set something that my teammates could easily understand.

Getting Started

The most basic kind of re-writing you can do is simply amending your last commit. On the command line this is accomplished with git commit --amend. The bigger rewrite-hammer is git rebase -i <ref>. This command will pop off all of your commits to the point specified by <ref>, provide you with a control file to edit and then re-apply your patches as directed.

The control file (a term I just made up) looks kinda like this:

pick 1cea777 Initial introduction of Merb.
pick 5fe7a19 Favor XML over HTML as the "default" content-type.
pick 6791134 Cleaned up the 'views' directory, out with the old, in with the new.
pick ae6adac Put lots of back-navigation links to make it nice 'n' easy to use.
pick 1da31ca Removed last vestiges of the RestServlet-related configuration and code.
pick b9fe3b9 Added error views, updated error-handling and improvised content dispatch.
pick bf92292 Routing cleanup. This is much more pleasant to read.
pick ec74c63 An attempt to get RSpec working with Maven and JRuby.

# Rebase 92ddc87..ec74c63 onto 92ddc87
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

The top section lists all of your patches, one per line. You can edit this section to do any of the following:

  • Reorder the commits (just move lines up or down)
  • Edit a commit (replace “pick” with “edit” or simply “e”)
  • Remove a commit (just remove the line)
  • Merge with a previous commit (replace “pick” with “squash” or “s”)

Think of this list like a program of execution. Once you save the file and return control to git, it will attempt to execute this program. I say attempt here because sometimes git runs into conflicts when it comes to re-ordering patches.

Editing Commits

When you mark a commit for editing (with “edit” or “e”) git will attempt to apply all patches up to, and including that commit, and stop. This threw me at first because for some reason I had the unreasonable expectation that somehow the changes in the last commit would only be applied to the working tree and, perhaps, the index. Instead, that commit is fully applied, but all commits past that are pending. To add to my confusion, there isn’t an easily accessible marker to indicate that you are in the middle of rebase (unless you frequently scan the .git directory as a matter of habit). At this point you could amend the commit (with git commit --amend) or insert other commits.

Sometimes I use this just to fix up the commit message. When I’m working on a new feature that has a lot of trial-and-error I tend to mark the first commit message with “WIP” to remind myself to review that patch and the ones following to see if I can clean them up. This is an area where git really shines. In a system like Subversion your audience (other coders who look at your changes) end up walking through whatever little mini-epic you’ve composed as you try things out, add things and remove things. This makes for some difficult reading for consumers of those patches and so a lot of folks tend to stack up big changes and then send in the big über-commit.

The problem with building the mega-patch is that you don’t have a lot of scaffolding under you while you are building it. If you go off and explore something that doesn’t turn out right, you generally have to do a lot of manual reverting. This simply sucks and is a waste of time. With git I can work in lots of incremental commits, then go back and edit them into something sensible once I’m ready to push changes.

Once you’ve finished doing whatever edit you want to do for that commit, simply type git rebase --continue and the remainder of the “script” will execute. If any other “edits” are in the pipeline, the process will repeat itself until the rebase is completed.

Squashing Commits

I looooove squashing commits in git. For any moderately complicated work, it’s rare that I get it right the first time. Usually as I go along I find some mistake I made or find a refinement that cleans up the original work. As often as not, it’s usually a couple of commits away so amending the last commit isn’t going to help me. But hey, no worries! I simply commit the change and leave a log message for myself to merge it with another commit. Then, when I run the interactive rebase, I can simply move this commit up the list and change it from “pick” to “squash” (or “s”) and let git merge the two commits.

When rebasing encounters a “squash” it will apply the changes in both commits. If successful, git will prompt you with a commit message file that includes the original commit messages of both commits. You can choose either, both or neither of these and save the file to continue.

Resolving Conflicts

Sometimes when applying a commit, git will run into conflicts and bail out on a merge. Whenever this happens to me I always have a little moment of panic as if I’ve broken something, but fear not—you can fix this. When this happens git tries to stage as many of the changes as it can. Any conflicts are left unstaged and need to be edited (look for the standard conflict markers), and then re-staged into the index. When you commit, git should show you the original commit message of the patch it was attempting to apply, which you can edit or keep. Once the commit succeeds, rebasing should automatically continue.

The Big Red Button

Sometimes you may just give up on a rebase. Either you can’t commit the time to it, you don’t really want to go through with it, or your patience has reached its limit. At any point, before the rebase has completed, you can execute git rebase --abort and your working tree, index and commit-log will all be returned to the state prior to starting the rebase. Think of this as the big red “stop” button for rebasing.

Playing Fast and Loose with Branches

If you come from other SCM systems like Subversion, you tend to treat branches as expensive and something you only use on occasion. With git, branches are cheap and easy like drinks in Tijuana. Be fearless! Not sure about some exploration? Make a branch!

If rebasing makes you nervous, and you’re not entirely confident that aborting will save you, I suggest creating a branch on which to rebase. Simply create a new branch from where you’re at with git checkout -b <branch>. You’ll be immediately switched to that branch with your commit log looking exactly like the branch you came from. Here you can rebase, edit, remove, add and generally go crazy with your commits.

Once you’ve got your commits where you want them it’s simply a matter of getting them back into whatever you consider your “main” branch to be and pushing any changes upstream. This works really well when you have rendez-vous point like a Github repo or an SVN server (we do a lot of git on top of Subversion at work). Assuming that you’ve been adding changes on your master branch, you might create a new branch off of master that you might call exp. On the exp branch you might rebase and wreak all sorts of havoc on the commit log. Once you have your commits where you want them, switch back to your master branch and reset it to point to the head of your upstream repo. If you’re using git all the way, simply merge your exp branch over. If you’re running git on top of Subversion, simply cherry-pick the commits on the exp branch (in order!!!) and push the changes upstream.

It’s hard to stress how important it is to shift your mindset into thinking in terms of sharing patches. Treat your commits like individual, digestible changes. Even if you’re working by yourself or in a small team, I still think there’s value in being disciplined with your commits.

Meet Magit!

January 18th, 2009

In the spirit of Geoffrey Grossenbach’s Meet Emacs Peepcode Screencast, I put together my own humble little screencast this weekend on magit, a fantastic git mode for Emacs.


Meet Magit from Alex Vollmer on Vimeo.

It’s not meant to be an exhaustive survey of magit (check the docs for all the details), but to show off some of the cool features this mode has. I found that spending just a little time with docs and learning this mode has already paid off in terms of increasing my productivity. Enjoy!

The Fast and the Quick

January 1st, 2009

Walter Payton

I’ve been a football fan since I was about five years old. I have studied this game for almost thirty years, so forgive me if I bore you all with a trite football analogy. This is the old saw known as “fast vs. quick”. Players like Barry Sanders or Walter Payton were “quick”, but not necessarily fast. In general, “fast” guys are wide receivers and corner-backs (the guys that cover the receivers). Receives generally have further to run than running backs, so they need what is called “breakaway speed” which is enough raw power to get away from the defender covering them.

Running backs however, need a combination of strength and the ability to move their bodies very quickly in a very small space. The difference between a gain of one or two yards and a breaking-off a twenty-yard run is usually a matter of inches. The runner has to be in just the right place at just the right moment and get just the right kind of blocking from his teammates. Quickness is the ability to shift weight, turn the body and plant a foot just a fraction of second faster than the next guy. It’s what separates the good from the truly great.

Hall of Fame running backs rarely survive on pure speed alone. Heck, most backs that were “burners” in college are usually forced to play another position at the professional level. Those that try to rely on pure brawn to break tackles generally don’t last long (see, Eddie George, Priest Holmes or any back that has played in Denver in the last decade). The really great ones have that ethereal quality known as “quickness”.

So, I was thinking lately about “agile” in the software world and what it really means. The term agile, isn’t clear enough—it could be fast or it could be quick. But which really matters? Which is the quality you really want to have?

My answer? You want the agility associated with quickness, not raw speed. Being “quick” in software might look like:

  • New requirements are handled in-stride and rarely, if ever, with The Big Re-Write
  • The time to produce a meaningful feature is measured in hours or days, not weeks
  • The time to produce a meaningful release is measured in days or weeks, not months
  • The system almost never looks like the original design

OK, so what would “fast” look like? Well…

  • Releases are buggy
  • Few if any tests
  • Code diarrhea
  • Quality is inconsistent
  • There are lots of dependencies
  • New requirements are an exercise in hammering reality into fixed model

Actually, none of those sound particularly “fast” to me.

When folks complain about the ineffectiveness of “Agile”, I sometimes wonder if they aren’t simply confusing fast with quick. There isn’t any methodology or toolset I know of that will make you faster. Your raw speed is determined more or less by the skill of your team. Each member transfers a concept into code at a relatively consistent rate, so you simply aren’t going to go any faster unless you change your team. However I think you can acquire new skills to improve your quickness.

Flaccid Attitudes

December 22nd, 2008

Today I had an impromptu conversation with a total stranger at my local café that got me thinking. He saw that I was working on some code and asked me what I was doing. I gave him the thirty-second whirlwind tour of Ruby and briefly explained what I was working on.

He came from the .net side of things and had been doing contracting for quite awhile. Recently though, his shop closed up and he was between gigs. He hadn’t been exposed to Ruby and thought it sounded kind of interesting. He was, as he put it, “a Windows-guy”, but basically apologized for it saying that “everyone around here” runs Windows. Really? You mean like the four-out-of-five-laptops that are Macs in this café??!!! (Note to self: this fella doesn’t seem too observant.)

So while I was trying to politely end the conversation to get back to my hacking and an IRC-meeting, he rambled on about his personal work philosophy. God knows how long he droned on, but his M.O. essentially boiled down to “Hey I don’t care what I work on. Languages are all the same, why fuss over this one or that one?”

It stopped me in my tracks.

Are you kidding me?

Look, there is something laudable (in a kind of John-and-Yoko-stay-in-bed-for-peace way) about The Big World view where all the geeks get along and sing side by side at the great binary campfire. At a certain level arguing over this language vs. that language or this tool or that operating system is frivolous waste of time. Much of our “values” in these things are based merely on opinions, aesthetics and feelings. It’s like mailing list arguments over whether or not the Enterprise could defeat the Galactica. Ladies and Gentleman on your left is Dork City…

But what this really told me more than anything else was that this guy was simply indifferent. You don’t have to agree with my way of doing things, but when we talk about them I at least expect you to have an opinion and to be able to back that up with some reasoning. This guy’s indifference stemmed from the fact that he treated this like a job.

“Passion” is a word that is overused in this biz. Every time I’m in a debrief about some candidate and the notion of “passion” comes up I started checking the room for forks to shove in my eyes. I don’t care about passion for The Company or The Idea. That’s rah-rah B.S. that I have no stomach or patience for. What I do want to see in a co-worker is someone who cares about what they work on and how they do it. This is your day-to-day existence. This is what you spend a lot of waking hours doing, being away from your loved ones. You damn-well better care about how you want to spend that time.

If you wanted to fail spectacularly in a job interview with me, one way to score a boat-load of demerit-points quickly is give an indifferent answer to the question, “What do you like to work on?” When people shrug their shoulders and say, “Oh, I’ll work on anything”, it tells me that they don’t care. The pay is the same, so why fuss over the details?

Now I understand that some interviewees won’t give me a straight answer because they expect that I want the answer an automaton would give. There are certainly plenty of shops that just want “human capital” in much the same way generals in WWI wanted troops (see fodder, cannon). But even so, I’m not sure that’s the kind of person I want on my team. Show a little back-bone for pete’s sake! Do you do this job just because it pays the bills? Are you so beaten-down by the industry and your experiences that you have no hope of it ever getting better? Are you just trudging forward in your profession because you don’t know what else to do?

I don’t care so much whether or not we agree on tools, languages or operating systems, but I hope to God you care about how you spend your time on this earth in this profession. Don’t sleepwalk through it.

Burning My Ships

December 20th, 2008

When Columbus reached the New World, he burned his ships. As a result his men were well-motivated.

This quote comes from the character of Marko Ramius, as played by Sean Connery, from one of my all-time favorite films, “The Hunt for Red October”. I love that quote in particular because I always think of it whenever I decide to tweak my process, my work environment or my tools. For all but the most trivial changes, you usually have to immerse yourself in it. So I usually “burn my ships” by leaving behind the old way of doing things to really burn the new way into my brain.

Sometimes the new way turns out to not be so great. That’s fine because that’s a satisfactory result of the experiment. If the “new way” turns out to suck, there’s just as much to learn (if not more) from a real crash-and-burn than success.

The first big “ship-burning” I did was very early in my career. I had been a few months into my professional developer career doing Java and decided that I really liked this Unix thing. So I completely wiped out my Windows NT work box and put one of the first versions of Red Hat on there. I figured if I was going to get good at Linux I was going to have to just jump in the deep end of the pool and learn to swim.

It turned out to be an absolutely wonderful decision. Throughout the years I moved through several distributions: Red Hat to Mandrake to Gentoo to Ubuntu. Each new distribution taught me something more about Linux than I knew before (especially true for Gentoo).

I’ve done the same trick with editors too. When I first started out I used vi for my Java development. I tried using the first IDEs (JBuilder, etc.) but they were all terrible. Plus, at that time a serious Java IDE for Linux was still a twinkle in Erich Gamma’s eye. I had a co-worker who was an XEmacs power-user and it looked like he got a lot done so I figured I’d give it a go—especially since I had on-site technical support. This was my first experience with Emacs and I never really got beyond basic editing. I wrote a couple of macros but that was about it.

Then NetBeans rolled around and I was more than happy to start using it. I had a decent intellisense feature and built-in Ant integration, both of which were a significant step forward to me. I ran with that for a couple of years until I started a new job where everyone was using this new-fangled thing called Eclipse. I tried to hold-out with NetBeans for a while, but after watching some others pull off some seriously cool tricks in Eclipse I knew it was time to give it a go. I’ve ridden that Eclipse horse for damn-near six years and I’d be willing to put my knowledge of Eclipse-editing arcana up against anyone.

Several years laster, on the operating system front, another big change was coming. I had been a die-hard Linux fan since my switch back in the Old Days, but by winter of 2005 I had run into a tangled knot of Linux-related headaches that really sapped the fun out of it for me. Between home servers and 64-bit laptop (in 2005!) I spent more time just trying to keep my machines up to date and running than actually getting anything productive done. However, it wasn’t until I went to my first Seattle Ruby Brigade meeting (when everyone there had a Mac) that I seriously considered switching operating systems.

This was the same time that I discovered Ruby. What attracted me to the language was not only the beauty of the syntax, but the underlying philosophies of pragmatism, simplicity and no-bullshit attitude. There seemed to be a similar attitude in Mac users and I found this approach appealing. This is not a knock on Linux. I love Linux, I just don’t want to use it for my desktop OS anymore. I don’t have the patience to fiddle with things that much anymore. I have lots of ideas and I’ll never get anywhere if I get bogged-down with irrelevant minutiae and yak-shaving.

When I switched to the Mac I got myself a license for TextMate which has definitely been the editor-of-choice for lots of Rubyists. However, as I blogged about before, it’s now time to get off the TM-train and switch (back) to Emacs.

So what’s the point of all of this? Am I just thrashing? Am I desperately throwing myself at each and every new tool on the block? You might think so, but I actually have some discriminating taste. I do try out a lot of tools because I’m always looking for some kind of edge, anything that I can leverage to get stupid busy-work out of the way. As I get older I have less and less patience for this sort of thing for productivity taxes. I just want to get something important done.

So, from time to time, a little alarm goes off inside my brain to remind me that it’s time for a change. Sometimes it’s something as simple as changing my terminal or editing font. Other times it’s things like learning a new language. Regardless, all of these things keep me from getting mentally lazy. Once I get mentally complacent, it’s game over. So consider if perhaps it’s time to “burn some ships” just keep things interesting.

Changed my keys around to Dvorak

Good heavens, some day I may even do something as crazy as switch to a Dvorak keyboard layout. That just might make my head explore—in a good way.

Just Having Fun

December 15th, 2008

After spending nearly all of my spare hours on moochbot, it was fun to take a lighter turn this week. Today I put up http://isthatfreedomrock.com. If you are lucky enough to have watched cable in the late 80’s you might remember a TV ad in which two hippies sit in front of a VW bus doing their best Cheech & Chong routine. One hippy says to another, “is that freedom rock? Then turn it up!” I don’t know why, but that has always been funny to me. It’s just so…stupid. Can you imagine the ad execs sitting around the table thinking this one up?

Anyway, one day it occurred to me that it would be funny (to me at least) to have a very simple, single-serving site that told you whether a certain song or artist was, in fact, Freedom Rock. Note the capital letters. I’m not talking Toby Keith “freedom rock” with waving flags in the background and lots of shiny pickup trucks. I’m talking about the rather odd, rag-tag collection of songs that made it to this album. Try playing with the site a bit, then check out the Urban Dictionary’s entry on Freedom Rock.

This leads to one of the pillars of my personal philosophy:

Amuse yourself first, worry about your audience later.

I wrote this primarily because it make me laugh…a lot. I don’t know why. It’s dumb, it’s juvenile and it’s totally worth the $10 I paid to register the domain-name.

But stupid-hippy jokes don’t make up the whole picture. The other half of this fun little excursion was figuring out how to do this with as little code as possible. At first I wrote this as a flat Merb application. Unfortunately I wanted to host this on Dreamhost and they are still on Ancient Ruby (read, 1.8.5) and the newest Merb wants 1.8.6. That was a deal-breaker. So then I took a look at Sinatra, and just like the bobby-soxers of the 40’s I fell in love. Sigh…

If you haven’t had a chance to look at Sinatra, you should do yourself a favor and check it out. They call it a DSL for the web, not a framework. It has the nice terse syntax of Camping, but has source that gives me half a chance to comprehend. It’s short and sweet and gives enough things that will make sense to Rails-veteran, but with little extra cruft. The source is up on GitHub (with a shocking number of commits for such a simple project).

Code Personification

December 8th, 2008

Today I had a conversation with co-worker about the two software components we were trying to integrate in the system we work on. In that conversation I noticed that we both kept referring to the software components as “you” and “I”. If you had been within earshot of this conversation you would have heard phrases like “…you should send the dates in GMT so that I can search correctly…” I don’t think this conversational style is uncommon among developers. Clearly it’s not logically correct—it’s not me sending dates, it’s my code. It’s not him who is searching, it’s his code. Why do we do this?

For some reason I’ve always been a little bothered by this and have always felt like it should be avoided. I dislike this way of speaking about a system because of how easy it is to personalize code that someone has written. I think it’s simply too easy to make a statement that sounds like a criticism of the person instead of the work. A criticism of the latter can be hard enough to take, but when it’s misconstrued with a personal critique it’s very easy for feelings to get hurt and team morale to take a nose-dive. In my experience it takes far longer to gain the trust of your teammates than it does to lose it.

The other reason I don’t like it is that it reinforces ownership boundaries around particular parts of the code. In an ideal world your team members would be able to move fluidly about the codebase depending on the features to be implemented. In reality this can become difficult, but like a lot of thinks in life I think it’s a good “stretch-goal”. So when we speak in personal pronouns instead of component names it seems to reinforce these barriers (or maybe it simply highlights them.)

I’ve found that it’s difficult to avoid talking about systems in these terms. I have to make a conscious effort to not do this in much the same way I have to remember to floss. Both seem like unnatural activities that require a lot of discipline to maintain. I can understand why I might be inclined to forget flossing regularly, but it’s not as clear to me why all of us developers want to personify code in our daily speech. Any ideas?

Proportional Code

October 26th, 2008

Few things are less sexy than command-line parsing. It is one of the most mundane tasks a programmer has to execute in their career. But, it surprises just how much code is required to do basic command-line parsing in a lot of languages, including Ruby. So I got to thinking, why does this bug me so much? I think the answer is that requiring so much code for such a relatively trivial task violates my sense of proportionality in the code. I hate having to say so much more about this teeny little task than I do about the “theme” of my code. I think it distorts the narrative of the code.

Let’s say that the processing of writing your program is like launching spacecraft. Ideally you would like to get from launch to cruising around in space as quickly as possible. The Star Trek universe solves this quite elegantly with the transporter. We don’t put you in a box and launch it, we break your atoms apart and transmit them to another location! That’s pretty cool, but maybe we’re just not quite that cool yet. Another solution is one proffered by the Star Wars universe. A ship like the Millenium Falcon can leave just about any planetary atmosphere any time it damn well pleases without the use of special equipment. It just flies away. Not bad.

Atlantis (STS-125)

However, here on earth, our primitive space craft need a tremendous amount of disposable apparatus to reach escape-velocity. The proportion of useful vehicle (the shuttle) to the orbit-busting mechanism (the rocket boosters and fuel tanks) is a staggering 5.4:1 (based on liftoff weight).

Command-line parsing in code exhibits a similar disproportion. The interesting part of your app isn’t the command-line parsing. Why should it take up such a disproportionate amount of space in your code? Those boosters quickly become “space-junk”, once the launch vehicle has left Earth; expensive trash that is never to be used again.

Space-junk is dangerous for the next guy that wants to launch into space. It’s also dangerous for the folks on the ground as it may decide to come crashing back down to earth. And those boosters have also been responsible for one of the worst disasters in NASA’s history. If we could only get rid of those damn things the whole space program just might be a little better off. Unfortunately physics, and our current space-flight capabilities currently require them.

But our code is a different story. We don’t have such physical barriers that handicap us. Any barriers we run into are usually of our own making. So why not try to reduce those as much as possible? Why say in more code, what you could say in less? Wouldn’t that cut down on bugs? Wouldn’t that ease the burden of maintenance? Wouldn’t that reduce the amount of information overhead you have to maintain each time you revisit that code?

Command-line parsing is a stupid, menial task that should require very little attention. By extension, it should only be given a stupid, menial amount of code to make it work. We have big ideas! They shouldn’t get bogged down by handling command-line options!

This is why I wrote Clip. Clip is an expression of the need to make the simple things simple, but no simpler. If you have modest command-line parsing needs, Clip rewards you with minimal investment. If you need something trickier, Clip allows you to say a little more to it and gain more benefits from it. You get to decide how much you want to engage—not the library.

This is one of the things I like about Ruby. The language is extremely flexible which gives me a lot of ways to “pack” ideas into code in a variety of ways. Having more than one way to do things isn’t all that useful by itself. But it’s essential when you want to write expressive code. Things like object literals, or one-line control-structure alternatives help me keep the lines of code proportional to the ideas they express.

This is also something I find challenging to do in Java. In languages like Java, even just creating a collection of objects requires quite a bit of code:

    1 import java.util.*;
    2
    3 public class Designer {
    4   public void makeItWork(List<Trash> trash) {
    5     // today's challenge: convert trash to wearable garments
    6     List<Garment> garments = new ArrayList<Garment>(trash.size());
    7     for (Trash t : trash) {
    8       Garment g = new Garment(t.getName());
    9       garments.add(g);
   10     }
   11
   12     submitToJudges(garments);
   13   }
   14 }

In Java we often solve this by pushing all of that code into a private method that is named something meaningful. This works pretty well, but does tend to result in an explosion of “helper methods”. Sometimes folks take the “cheap” route and simply prefix these riffs with explanatory comments like “convert each Trash into a Garment”. I’m not a real big fan of this. Generally I don’t care about the object conversion in the first place because the rest of the code is presumably doing something interesting with the Garments and I don’t give a damn about the Trash.

So let’s look at it in Ruby:

    1 class Designer
    2   def make_it_work(trash)
    3     submit_to_judges(trash.map { |t| Garment.new(t.name) })
    4   end
    5 end

By my count there are five lines in the Java example (including the comment) just to convert trash to garments. In contrast I boiled that down to one line in Ruby. OK I could have done this in two lines if you think that’s too much of a long-train. But I think there are couple of important points here:

  1. The importance of the concept being expressed diminishes from left to right
  2. The attention-span of the reader diminishes from top to bottom

The Ruby example beats Java on both counts. I don’t waste a lot of the reader’s attention span up-front on book-keeping details (in the vertical space) and I state the important thing I’m trying do (submit my top Foos) quickly (on the left). The details of which Garments I’m dealing with are merely a qualification of what I’m trying to do.

How you handle these two dimensions is greatly affected by both the language you use and the APIs you deal with. This is one of the reasons that I do not find the use of scripting languages for Java’s Swing API all that compelling. Scripting languages like JRuby or Jython help me with the horizontal space, but don’t do a damn thing for the vertical requirements. With an awful API like Swing I have to say a lot of words to make it go, regardless of the language I do it with.

Getting back to my dumb example, being on such a small scale this may not seem like a large impact. But multiplied several times over to match the size of most projects, this kind savings can really pile up. The difference in the amount of code required by these two approaches is manifested in a savings in cognitive investment required to grok these projects. This is the very essence of maintainability and sustainability. Anytime you can do more with less, you come out ahead.

At great peril to my own geek cred, I will say that this is why I find The Lord of the Rings to be such an awful piece of writing. It is so full of peripheral and non-essential information that finding the real story or characters requires extraordinary patience and concentration on the part of the reader. If Tolkien had been more concerned with the story and less with “world-building” I’ll bet he could have gotten that story boiled down to a single book.

Now I realize that a lot of folks love the Tolkien books for the very reasons I criticize it. That’s fine, that is an argument about aesthetics, not facts. However I would strongly argue that “world-building” in your code is a bad idea. I think you’re much more likely to build a decent piece of software if you pack your ideas tightly like a William Gibson novel than as a sprawling “trilogy” of epic code. Go ahead, prove me wrong. I double dog-dare ya.

OK, so by this point any credibility I may have had is gone. Look at the size of a post about saying more with less. In the hope that you might be lazy and like to skip to the end:

Do as much as you can…with as little as possible.

Back To My…Emacs

October 6th, 2008

Emacs. Love it or hate it, it is undeniably a monument of software engineering. At best it’s an amazingly customizable work environment that can be shaped to your every whim. At worst it’s a giant time-sink where productivity is skewered by endless “fiddling”.

Since switching to the Mac over a year and half ago, I’ve used TextMate as my non-Java editor. TextMate is great text editor. It’s relatively simple to extend, has a very active community and only takes a little investment before a user gets productive. But I’ll admit that in the last month or so my eyes started wandering from TextMate—I felt like maybe I was ready to go back to Emacs.

Perhaps it’s worth a little history first. Back in the Dark Ages of Java Development (anyone remember Gnu Server Pages?), I was a pretty hard-core XEmacs guy for my Java dev. At the time Java IDEs were painful exercises in waiting and crash-recovery. JBuilder, early NetBeans, Visual Cafe were all valiant attempts but terrible failures. So I rode with XEmacs until the IDEs caught up.

Then one day I met Eclipse. Unlike any other Java editing tool, Eclipse was much more than a text-editor. Rather than treating your code like text to be manipulated, Eclipse actually understood your code. This allows you to think in terms of manipulating Java syntax and symbols instead of simple text tokens and lines. For a static language like Java this is incredibly powerful since you can determine up-front all of the possible things you might want to write. This is why a full-on “intelli-sense” feature for dynamic languages is hard to do as well in static, compiled languages.

I spent the next five years learning just about every nook and cranny of Eclipse and would put my raw Java-writing skills up against anyone. Even now, I still use Eclipse for Java and I can’t imagine going back to a plain text-editor—even a souped-up hot-rod like Emacs. This says less about the deficiencies of any text editors as it does about the requirements for developing in Java. Writing Java without all of the code-completion and refactoring tools an IDE like Eclipse has would simply exceed my pain threshold. So while Eclipse has become quite bloated lately and, when coupled with tools like Maven, is an exercise machine-servitude, it will be a cold day in hell before I give it up for Java. (NB: I plan on giving up Java-dev first.)

Now I’m writing a lot more non-Java than I did a year ago. That’s what brought me to TextMate. The integration for Ruby, HTML, CSS, JavaScript and shell was outstanding. I bought the TextMate book and was on my way to editor ass-kicking.

Unlike my Java days, now I identify myself less with a single language. Back in the day I was a Java Programmer™ dad-gummit. It was The One Language To Rule Them All and it served me well. Do you remember those days? Yeah, that was also the time when certified Oracle dudes were writing their own checks. But as time went on, I noticed that those Oracle guys pretty much knew how to do one thing and if and when the Day of Database Reckoning ever came, these guys were gonna be left standing in the cold wondering what the hell happened. I think that day has come and those dudes are becoming the equivalent of COBOL programmers—relegated to propping up legacy systems and talking wistfully about “the good ol’ days”.

So it got me to thinking about what I needed to do to survive in this business. Clearly I was going to have to evolve. So I started looking around for some inspiration and came across Ruby. Right now it’s my favorite language, but it’s not the only game in town. Ruby borrows a lot of features from other languages and a lot of other Ruby-ists are also spending time with other languages like Haskell, Erlang, io, and Lisp just to get exposure to other ideas. Moving away from a single-language focus to broader interests has been an important part of moving from rookie to journeyman. Evolve or die, right?

So how does this relate to Emacs? Well, like a lot of folks, I’ve been interested in learning more about functional programming. The problem is, I simply haven’t had the time to crack open the Erlang book and bend my brain in new ways. Don’t get me wrong, it’s on the list, but it’s going to be a while before I get to it. So I was eager to dip my toe in FP without a major commitment. Enter ELisp.

Before I dropped out of college, my brief career in academic computer science was spent with Scheme. My time in school didn’t end well and so I’ve associated Scheme (and by extension, Lisp) with that particularly unpleasant time in my life. I’ve only recently overcome the shakes when I see car or cdr. But a little time and some professional success has healed old wounds. In my first go-round with Emacs, I was really just using it as a power-editor. The internals of Emacs pretty much escaped me and in my mind there was a pretty major barrier between an ELisp user and an ELisp writer.

This time I’ve made a concentrated effort to learn more about how Emacs works. I’ve been racing through the O’Reilly Emacs book and this time it makes sense. I don’t know what the hang-up was before, but this time it all seems so logical! The entire editor is simply a collection of ELisp functions and variables built on top of other functions and variables. It’s all self-documented and incredibly dynamic. Wanna try something out? Just put a little Lisp in your *scratch* buffer and evaluate that sucker. Hell, in Eclipse I’d have to download the freakin’ source and compile it or swim in XML writing an extension. That’s incredibly powerful—the barrier to “trying stuff out” is mind-bogglingly low.

So while I’ve definitely take a short-term hit by trading in TextMate for Emacs, but I’m reaching productivity-parity pretty quickly. A couple of modes/libraries I’ve found that I’ve really liked are:

I plan on spending some quality time with some of the various snippets libraries too to port over some of the templates that TextMate uses. For something like Rails development, which is about the most idiomatic programming I can imagine, having short-hand snippets is a major productivity boost.

So why go through this? After all, switching editors can be like converting from Catholicism to Judaism for some. Well, I think I’m doing this because:

  • I’ve already overcome the initial steep-learning curve of basic editing in Emacs
  • I get a nice, no-commitment introduction to functional programming
  • I get a great environment to learn new stuff in
  • With a little effort and a willingness to learn, I can make this sucker to anything
  • Emacs has quite a track-record. It’s close association with Unix is no accident.
  • Emacs customization is easy to write and a snap to track in SCM

I can’t say that I’ll use Emacs for everything. I’m getting into Cocoa development too and it looks like doing that outside of XCode is a fool’s errand. But that’s okay. I don’t need a single tool to do everything for me, just a handful of tools that help me get a variety of things done. That said, I’m pretty sure I’ll be solving a lot more problems in Emacs than I ever did in any other single tool.