Recent Posts
Singleton is one of the most beautiful patterns in the world. Let’s take a few minutes to appreciate it:
public class Siren
{
private static Siren instance;
private Siren() {
}
public static Siren getInstance() {
if (instance == null)
instance = new Siren();
return instance;
}
public void sing() {
…
}
}
Beautiful isn’t it? Let’s examine why. Singletons are beautiful because they rely on an interesting interplay between access protection and static scope. When you create a singleton, you get two effects: a global point of access and a guarantee that there will be only one instance in your program. Two for the price of one. How can that be bad?
Now, I know what some of you are thinking right now? Is he nuts? Doesn’t he know how much trouble I’ve gotten into with singletons? They are, after all, global variables so they can lead to a great deal of coupling. Moreover, unit testing in the presence of singletons is acutely painful if they manage mutable state. If one test modifies the state of a singleton any other test that indirectly accesses that singleton could just be silently wrong.
I know how painful singletons are, and there are countless accounts of Singleton pain out there. But, still I want to talk about what is beautiful about Singleton because it is an insidious type of beauty; one that we should all be cautious of.
Two for the Price of One
I wish I had a single word for that phrase two for the price of one, particularly in the software domain. When I try to explain it to people who aren't programmers, I use a particular type of hair dryer as an example. I encountered it at a hotel once. It looked like a normal wall mounted hair dryer but it didn't have a discernible on/off switch. When I took it off the wall mount, it turned on. When I put it back on the mount, it turned off.
Personally, I think it's hard to be a tech person if you don't feel a bit bright inside when you see something like that. If I had to articulate the feeling, I'd say "Check it out.. one gesture, two effects!" You're going to hang up the dryer anyway, so why have a separate switch? It's a beautiful hack.. and in a way, part of the essence of design.
Clever, Clever, Clever..
The more I think of this quality, the more I think that it has something to do with economy: the idea that if you are clever, you can get more done with less material or less action. In a way, it's the basis of engineering. We're supposed to make things easier for the user, and we're supposed to make things cheaper when we can. If we can use the same mechanism for multiple things, it's a clear win, isn't it?
Let's look at Singleton again.
Singleton is a single mechanism that gives us two effects: a global point of access, and the assurance of a single instance. It's fine as long as we don't mind having those effects together. What if we wanted them separately?
Can we have a pattern which gives us a global of access without an assurance of a single instance? Sure. All we have to do is create a public static variable in a class:
public class Global
{
public static Global instance = new Global();
}
Can we have a pattern which gives us the assurance of a single instance of class without global access to the instance? That's harder. We can try to do something like this:
public class LocalHolder
{
private static Local instance;
public Local getInstance() { // note: non-static method
if (instance == null)
instance = new Local();
return instance;
}
}
In this example, we must create an instance of LocalHolder to get the singleton instance, but frankly, we can create LocalHolder instances anywhere and, through them, access the single instance of Local. We haven't done much to constrain access to that instance. It's still possible to access it anyplace.
But, that leads us to the beauty of Singleton. Singleton gives you two effects, one of which is difficult to achieve on its own, and those effects are tied together in a single mechanism. Two for the price of one.
The Price of Clever
So, I'm still looking for a word for this two for the price of one quality. It would make it easier to talk about. But, in lieu of a good term, I'll call it Quality X for now.
Quality X can be very useful in engineering, particularly when costs matter. If you can use the same mechanism for multiple things, you've created value out of nothing. But, there are hidden costs. Sometimes, Quality X can lead to bad effects. A hair dryer that doesn't turn off unless you hang it up could be hazardous in some situations. On the other hand, if you can work through those problems, Quality X may be appropriate.
In software, I'm particularly suspicious of Quality X. Yes, you get some economy from it and some things that are difficult to achieve independently can be easier to achieve when you glom them together, but we have name for that already. It's coupling, isn't it?
Singleton can be useful, but it can also be abused in nightmarish ways and most of them have to do with the coupling of the two effects it produces. The price of singleton-ness is the possibility of global access, and people do take advantage of that global access.
Singleton is beautiful, but it's a seductive beauty. The sort of beauty that can be dangerous if you're not aware of it's ramifications. And, I think that the root of it is that quality: Two for the price of one.
About five years ago, I was visiting a company on the east coast and I sat with one of their developers. We were about to make some changes in a method that was a couple hundred lines long and I said “Let’s break this method down a bit; let’s do some extractions.” The developer looked at me and said “Oh. You’re an academic.”
I don’t think I’ll ever forget that incident. I knew that I probably wouldn’t get much mileage out of saying “Hey, the best programmers I know would say that this method is ridiculously long, if you don’t see it that way, I don’t know what to say.” So, we worked together for a while and it snuck up on him. We got to a point where it was obvious that we had to do something different, and sure enough it was extract method.
The fact is I didn’t have the heart to tell him that it was a bit worse than he thought. I’m not an academic, but I do like to factor my code to a very fine grain. I like to break methods down into itty bitty pieces so that every single one of them does exactly one thing. They’re one to five lines, ten or twenty lines max; and, in my opinion, they’re beautiful.
Here’s an example. I was writing a utility a while ago that produces specialized source code wrappers for classes in java libraries. As I was working on it, I noticed repetitive formatting. I pulled it out into a class and this is what I ended up with:
package glaze.tool;
public class Formatter {
private String text = "";
private String indentation = "";
public void newLine() {
newLine("");
}
public void newLine(String lineText) {
newText("\n" + indentation + lineText);
}
public void newText(String newText) {
text += newText;
}
public void indent() {
indentation += "\t";
}
public void outdent() {
if (indentation.length() > 0)
indentation = indentation.substring(1);
}
public String getText() {
return text;
}
}
The methods are ridiculously small but they form a little language that reads rather well in code. Here’s an example of its use:
package glaze.tool;
import java.lang.reflect.Method;
public class GlazeInterface extends GlazeType {
private final static String INTERFACE_NAME_PREFIX = "I";
public GlazeInterface(Class clazz, ClassStore store) {
super(clazz, store);
}
@Override
protected void buildDeclaration() {
out.newLine("public interface " + getName() + " {");
out.indent();
buildMethods();
out.outdent();
out.newLine("}");
out.newLine();
}
protected GlazeMethod makeGlazedMethod(Method method) {
return new GlazeInterfaceMethod(method, store);
}
public String getName() {
return INTERFACE_NAME_PREFIX + wrappedClassName();
}
}
Now, if you’ve encountered code like this before, code where all of the methods are very short, you might have cursed the person who wrote it. It looks overfactored, but is it? Most of the methods ended up this small because I was very zealous about removing duplication, and it’s hard to argue for duplication. On the other hand, I have to admit that the code is a bit opaque. It takes time and study to see how the pieces fit together, but once you understand, changes are often easier and you don’t have to touch as much code to make them.
I spend a lot of time helping people in ugly sprawling code, so it's nice when I get a chance to factor code finely. I don't think I'm alone. I've seen a number of examples of this coding style over the years.. a Java port of the HotDraw framework, an early version of emacs, various implementations of the STL in C++.
If you haven't taken a piece of code and tried to squeeze out every bit of duplication, try it as an experiment. See what happens.
The Beautiful Code web site is just being launched. I'd like to give new-time visitors some perspective so that they realize, as they read particular postings, that no single posting should be taken as representative.
While writing the afterword to the book Beautiful Code, where I tried to draw some broad lessons from its essays, I finally decided to start by stressing their diversity:
Beautiful code surveys the range of human invention and ingenuity in one area of endeavor: the development of computer systems
Looking at the book again to draw inspiration for an interview with the maintainer of this web site (Bruce Stewart), I decided I could go even further:
Beautiful Code is a snapshot or time capsule of programming today. Everything is there, from the timeless and elegant to the dark corners of hackerdom. The range of languages, operating systems, and other environments represented is also historic. If you read the whole book, you pretty much know the whole field.
So my message comes down to the following. As I say in my afterword, you should make the "long and eventful journey through the whole book." And keep coming back to this site. The scope is broad, and if possible is likely to grow.
Over on ONLamp chromatic has posted the details about a Beautiful Code panel discussion taking place next week at Powell's Tech Books in Portland:
Next week is OSCON, so there will be plenty of wonderful programmers in Portland. We’re taking advantage of this to host a Beautiful Code discussion panel at Powell’s Technical Books, just across the river from the conference.
Wiki inventor Ward Cunningham will moderate the panel with Subversion designer Karl Fogel, Linux kernel maintainer Greg Kroah-Hartman, Haskell contributor Simon Peyton Jones, and Perl and Parrot hacker chromatic. Karl, Greg, and Simon all contributed chapters to Beautiful Code.
Aesthetics... what can you do?
When I was a younger programmer, I felt guilty about being a neat-freak. It was a selective obsession. There I was, sitting in my office with stacks of papers and books covering every available space, but I was oblivious to it. As long as my code looked great, I could shut out the chaos around me: the towering stacks of dead tree that could've toppled and crushed me if I had sneezed.
I don't know why I felt bad about being that way, but in retrospect, I think that I felt that I was wasting time caring about neatness in code. It took me a couple of years to figure out that the ergonomics of code matter, and that the time you spend decluttering your code can declutter your thoughts as well.
Because of this personal history, I've been a bit sensitive about the "real code" vs. "example code" distinction. A few days ago, Bryan Cantrill blogged about Brian Kernighan's example in the Beautiful Code book:
While I confess that I like writing a neatly recursive routine, I also find that I frequently end up having to unroll the recursion when I discover that I must deal with data structures that are bigger than I anticipated -- and that my beautiful code is resulting (or can result) in a stack overflow. (Indeed, I spent several unpleasant days last week doing exactly this when I discovered that pathologically bad input could cause blown stacks in some software that I'm working on.)
To take a concrete example, Brian Kernighan has a great chapter in Beautiful Code about some tight, crisp code written by Rob Pike to perform basic globbing. And the code is indeed beautiful. But it's also (at least in a way) busted: it overflows the stack on some categories of bad input. Admittedly, one is talking about very bad input here -- strings that consist of hundreds of thousands of stars in this case -- but this highlights exactly the problem I have with recursion: it leaves you with edge conditions that on the one hand really are edge conditions (deeply pathological input), but with a failure mode (a stack overflow) that's just too nasty to ignore.Now, there are ways to deal with this. If one can stomach it, the simplest way to deal with this is to setup a sigaltstack and then siglongjmp out of a SIGSEGV/SIGBUS signal handler. You have to be very careful about doing this: the signal handler should look at the si_addr field in the siginfo and comparing it to the stack bounds to confirm that it's a stack overflow, lest it end up siglongjmp'ing out of a non-recursion induced SIGSEGV (which, needless to say, would make a bad problem much worse). While an alternative signal stack solution may sound hideous to some, at least the recursion doesn't have to go under the knife in this approach. If having a SIGSEGV handler to catch this condition feels uncomfortably brittle (as well it might), or if one's state cannot be neatly unwound after an arbitrary siglongjmp (as well it might not), the code will have to change: either a depth counter will have to be passed down and failure propagated when depth exceeds a reasonable maximum, or the recursion will have to be unrolled into iteration. For most aesthetic senses, none of these options is going to make the code more beautiful -- but they will make it indisputably more correct.
Bryan's blog awakens all of those old feelings in me. Is it wrong to appreciate the beauty of Pike's recursive algorithm? To want to preserve it as unsullied as possible in production code? Or is that a trap that beautiful code can lead us into?
What do you think?
Well, it's arrived. I got my copy of Beautiful Code in the mail the other day. It's great to finally have it in hand.
When Greg Wilson asked me earlier this year if I'd contribute, I was surprised. The thing that I'm best known for in the industry is my work on legacy code. I wrote a book on the topic a few years ago, and (understatement alert) there isn't much beautiful code in it. It's about unmanageable code that thwarts our aspirations: huge classes, tortuously long methods, and dizzying levels of indentation -- code that inspires fear more than appreciation.
Working on that book was a bit scary. The remedies that I had to offer didn't exactly make code look better. In fact, sometimes it ended up looking worse. I thought that some people would think that I don't know what good code looks like, or that I don't really appreciate it. But, frankly, nothing could be further from the truth. I love code that is clean and beautiful. There's nothing I like more than visiting a project and seeing some area of code that just glows with intelligence and craftsmanship. When we do it right, there's an art to what we do.
Over the next few months, I'll be blogging here with several other folks and writing some articles. Hopefully we'll have some lively discussions.
It's worth taking time to examine the great things, the inspiring systems. The more we celebrate them, the more we'll emulate them.

