Where leading programmers explain how they find
unusual and carefully designed solutions

Recent Posts

Michael Feathers

Call it a crisis of faith.

I'm sitting today, looking at some code, and part of me is disgusted. I know that I or any number of people could've done better with this code, but, well, we didn't. The code is what it is. Some of the methods are long, some of the classes are big. The code isn't a shambles. There are some very nicely factored methods that are almost crystalline in their structure, and they brighten up the rest of the code. All in all, we could've done better, but we didn't.

There comes a point when you look at something that has continually annoyed you and you realize that no, it isn't a complete mess. Yes, it's a bit disheveled, but there's a sort of beauty there. It's organic, and organic things have their own structure and form. They start simple, grow into use, and then they start to age and deteriorate. I think that anyone who has programmed for a while can map that biological cycle to code. If you're prone to be distressed by it, you have the opinion that code just doesn't die soon enough for your tastes. I know I've felt that way many times. But, seriously, if we can see this sort of biological quality in our code, why are we so upset by it? Methods and classes growing over time.. it should be the most natural thing in the world, shouldn't it?

I guess it comes down to our orientation to our code. Code isn't like a pet that we can admire for it's lovable qualities (or, maybe it is, we often have to clean up after it). Code is more like a working material. We have to understand it and cast our thoughts in it. When we can't shape it easily, it frustrates us.

A while back, Larry Wall described Perl as a post-modern programming language. What he meant was that Perl doesn't say that there is just one right way to do things. When you look at the language you realize that you can do just about anything you want to do, and you can do it in at least three or four ways. It's a cool idea, but.. you know... give me a real simple language with only one way of doing things. Give me a code base where all of the methods and classes are well factored and well named. Many of us like order because it just makes things easier. Every little bit of order is a like a little promise. It says "If you understand this one thing, you'll understand more. It all means sense.. it really does."

So, we have this tension between what we want, and what code seems to want to become. We strive for order, but we're surrounded by entropy. Giving up doesn't seem right but neither does working against the grain of software.

Maybe there is another way.

Michael Feathers

We're in a curious state right now in the OO programming language arena. On the one hand, we have people who are pushing static typing further and further. On the other hand, there's a been a resurgence of interest in dynamic typing. Ruby and Python get more and more popular every day.

I don't think that these two trends are disconnected. I've run into a number of people who look at generics in Java and just say "why?" In certain domains, you want every assurance you can have. But, the conceptual overhead of what are, essentially, two completely different type schemes (parametric and subtype polymorphism) in one language is undeniable. It's like building a bridge in which all of the left-diagonal pieces are one type of metal and all of the right-diagonal pieces another. It's complicated and you end up with an incredible moiré pattern. It's rather hard for me to believe in that this is the best that we are capable of in the industry.

For me, the most interesting bits in statically typed OO programs are the places where you can use the two both forms of polymorphism to subvert static typing entirely. One of these is the boost::any class in C++.

boost::any allows you create a dynamic typing wormhole in C++. Here's how it works. boost::any is a class which holds any value object. For instance, you can create an any from a character pointer like this:


boost::any anAny("Hello There\n");

And, you can make an any from a long like this:


boost::any anotherAny(1L);

Since any is just a copy constructible value class, you can copy anys here and there:


vector<boost::any> container;

container.push_back(anAny);
container.push_back(anotherAny);

And recover the values using a cast:

long value = boost::any_cast<long> (anotherAny);

If the cast doesn't match the value in the any object a bad_any_cast exception is thrown.

The implementation of boost::any is rather tricky. It uses templated constructors and an internal "holder" template class that mixes subtype polymorphism and parametric polymorphism to allow it to vary with the type of the object it was created with. If you want to see the details, they are here in the source.

Yes, static typing can be useful, but it's nice to have an "out." The cool thing about any is that it allows you to have to tight assurance when you need it. You can't use the value of an any without casting. But, you can use it to get a bit of leverage in the moiré that would be hard to get otherwise.

Michael Feathers

The other day, chromatic blogged about his experience writing a Haskell version of the regular expression matcher that Brian Kernighan described in Beautiful Code:

I’ve been reading Beautiful Code, picking out chapters here and there as I have time. While reading Brian Kernighan’s explanation of Rob Pike’s regular expression program from The Practice of Programming, I had an idle thought. “Hey, that’s a highly recursive program with complex behavior suitable for didactic purposes.”

Of course, Kernighan says that almost verbatim in the text. He also says “It’s a nicer example than Yet Another Fibonacci Sequence Generator.”

So I ported it to Haskell. I don’t promise it’s necessarily great Haskell, and I wouldn’t consider it entirely beautiful, but it appears to function.

It would be neat to see a Haskell version that attempted to hide the recursion. I wonder what that would look like?
Michael Feathers

When I think about what we do in software development, I find it hard to imagine similar things happening in other fields.

Imagine being a car designer. Someone walks up to you and says "These are the requirements for the new car. It has to have four doors, a hatch-back, manual transmission, a wheel base of X and fifteen drink holders."

"Fifteen?," you ask quizzically. "Yes," they reply, "that's what marketing wants."

Now, it may happen like that -- I don't know -- but somehow I suspect that it doesn't.

After all, when we think of automotive design, we think about those very things.. how many doors does it have? Does it have a hatchback? Those aren't requirements, those are design decisions.

Maybe requirements is just a word that we use because we're dividing our design work between two groups.. a group that determines the higher level design (what the product will do); and the lower level design (how the product will do it).

Like any other division in development, this division of design can have negative effects, but I suspect that most of them time they are hidden.. they express themselves as lost opportunities. However, if you see the opportunities, you can do something special.

Kent Beck, Joseph Leddy, and William Wake gave a great example in Cutting with the Grain: The Rhythms of Design:

A more daring strategy .. [in software] .. is amputation. In abandonment you stop adding functionality in a certain direction. In amputation you abandon and remove all similar features. If a little is bad, perhaps none at all would be best.

An example of amputation is the security policy in Ward [Cunningham]’s Wiki. The collaborative nature of a Wiki makes it tempting to add security: editors of a page should at least have to log in first, shouldn’t they? Once you start adding security features, though, it’s hard to see where to stop. Instead, Ward chose to eliminate all technical notions of security from the Wiki.

Successful amputation is rare and precious. Amputation is rare because it requires a new way of looking at a problem and the courage to leave out conventionally-demanded features. Amputation is precious because the effort not expended on a class of difficult-to-implement features can be turned to create innovative features along some other dimension.

A large-scale application of amputation is what The Innovator’s Dilemma calls “changing the basis of competition”. Small entrants to a marketplace necessarily have to pick their battles. One way to do this is to amputate the strengths of competitors from your product, staying with the grain for the features you do implement, and building a compelling product that won’t or can’t be compared directly to established competitors. JUnit did this by using Java for its scripting language instead of the proprietary scripting languages of other testing tools.

There's great power in seeing requirements as design decisions.

No, the more I think about it, the notion of requirements just seems to be wrong. It's all design.

Michael G Schwern

In Design Sense, Michael Feathers ponders how to teach what is and is not a good design. He mentions an exercise to help think like an artist; flip a picture upside-down. This eliminates the bias of recognition; it's not a face or a flower, it's just a series of lines and shapes. Is there anything similar for coding? Where are our biases?

> continue reading
Andy Oram

What's been considered a superb model for good coding (in 1960's-style FORTRAN, no less!) for some thirty years? It's Will Crowther's Adventure, a game in the tradition of Dungeons & Dragons, but based on a real cave. His source code has recently been released online, and an article in Digital Humanities Quarterly, cited widely around the Internet (including Slashdot) analyzes it from many perspectives. > continue reading

Andy Oram

I sent a copy of Beautiful Code to author and .NET developer Pete Bromberg (http://www.eggheadcafe.com/). He writes:

The thing I liked most about "Beautiful Code" is that it puts you inside the heads of top thinkers in a number of different disciplines with concepts that transcend platform and language. As a primarily .NET developer myself, I was fascinated with Charles Petzold's treatise on dynamic code generation for graphics filters - a concept that applies in a number of different business scenarios.

> continue reading
Alberto Savoia

In Part I, I mentioned one of the dilemmas voiced by developers who want to inject some beautiful code in their day-to-day activities:

“I am maintaining a steaming pile of legacy code that I have inherited. I can barely keep the code base working – sort of. I would love to write some beautiful code, but have no time to think about beauty as long as I am saddled with this ugly code base.”

This is a very common situation. Most developers spend most of their time maintaining/enhancing code that they did not write and, more often than not, that code base is not just ugly, but coyote ugly*.

So, what’s a developer to do when stuck with code so bad that it should come with an “abandon all hope ye who enter here” warning? There are three basic options (besides the extreme the coyote option – which I don’t want to offer for legal liability reasons):

Option 1: Run for the hills (i.e., ask, beg, bribe for another assignment – or quit).

Option 2: Accept the job with resignation. Abandon hope and prepare yourself for a coding life of quiet desperation highlighted by moments of sheer panic. Help to prove that Thomas Jefferson was spot-on when he said: "Mankind are more disposed to suffer, while evils are sufferable, than to right themselves by abolishing the forms to which they are accustomed.”

Option 3: Accept the job as a challenge. Accept that the code base is ugly; it’s OK – therapeutic even – to make fun of it and of the careless, incompetent, so-called-programmers who developed it. Accept the fact that you cannot single-handedly turn a huge steaming pile of legacy code into a thing of beauty. But be determined and committed to reject and eliminate ugliness in the bits of code that you do touch. In other words: scorn globally, act locally.

The first option is probably the smartest one but, with so much crappy legacy code out there, you might have a hard time finding a suitable job. The second one is the easiest, but is not something that I would ever consider or recommend. The third option is the hardest to embrace, at least at the beginning, but the noblest and the one I want to talk about.

Since it’s unlikely that you will have the option to make sweeping design or architectural changes, the key to success in working with a pile of ugly code is to focus on small improvements. When you run into an ugly bit of code that you can or must change, make a conscious decision to make it more beautiful.

This, of course, raises the issue of what “more beautiful” means. If you have read Beautiful Code, you have probably realized that each author had a personal definition, or bias, for what constitutes beauty. The good news is that since you are the one working on the code, you can apply your own criteria for beauty.

Here are just a few of the many localized actions that you can practice – assuming you agree with my criteria for beauty:

- Write tests for a particular piece of code before you change it. A test suite is a beautiful thing to have and it will give you a safety net as you make those changes. If you are working with legacy code, you should become an expert at writing characterization tests**.

- Refactor to reduce complexity and improve testability. Method extraction is my favorite refactoring; it’s fast, safe (especially if you have tests), and easy to revert if needed. In my book, any method with a cyclomatic complexity of 8 or more is a candidate for refactoring.

- Rename cryptic or ambiguous identifiers. This is a pet peeve of mine. In this age of cheap computing resources there’s no excuse for using a variable name like “ac” instead of “areaCode”.

- Delete. If you can identify dead, useless, or obsolete code, get rid of it.

Sounds like easy and obvious advice, doesn’t it? Well, it might be easy and obvious but, unfortunately, it’s rarely practiced. Otherwise I would not have bothered to write this. The reality is that, in most cases, ugly code becomes uglier as it’s maintained or enhanced. As a matter of fact, a lot of code starts out pretty nice and clean (both in design and implementation) and degrades as time goes on. It happens gradually. It’s done innocently. In the short term, adding yet another if statement inside a nested for loop is faster and easier than taking some time to think of a way to refactor the code to reduce complexity; it does not look like a really bad thing. But over time, these actions add up.

Taking time to write a little test, perform a simple refactoring, or rename one variable, does not sound like much; but it represents a huge – HUGE – change in attitude and a rare and courageous stance toward legacy code. It means that you don’t accept the inevitable slide from ugly code to uglier code.

Reducing ugliness in legacy code one method at a time, may not be as glamorous as creating a few lines of beautiful code suitable for framing, but I would argue that it might be just as important and a far nobler thing to do – and you’ll never run short of opportunities to practice it.

Alberto

* Coyote ugly: code so ugly that some developers might prefer to chew their fingers off rather than work on it – much in the same way that a coyote captured in a jaw trap will chew off its own leg to escape certain death. Sorry if this is a bit too graphic.

** Characterization tests: a term coined by Michael Feathers in his excellent book Working Effectively With Legacy Code to describe tests that capture not the specified, but the actual, behavior of a piece of code. See: Characterization Test and Working Effectively With Characterization Tests

Michael Feathers

Design Patterns. We all know what they are. You can’t go very far in software development today without having heard of the factory pattern, singleton, or visitor. It’s been about 12 years since Design Patterns: Elements of Reusable Object Oriented Software was published and there have been countless patterns books released since then, but few have come close to the coverage of that original book. The four authors, Erich Gamma, Ralph Johnson, Richard Helm, and John Vlissides did the research and created a classic. They described 23 elemental patterns that, for the most part, have stood the test of time. Except… in my opinion.. they missed one, and I think it's one of the most elegant design patterns around.

Let’s take a look at it in context. Suppose that we have an IDE written in Python and we have a screen with various window panes. Each pane shows one or more program elements. There’s a pane that contains the list of classes, a pane that contains the list of methods for the selected class, and a pane that contains the selected method. To make this work, we need a class that represents classes and it needs to have a method which (among other things) returns the currently selected method of the class:

class TDEClass:
    def get_current_method(self):
    	return self.current_method
    ...

When the selected method pane needs the selected method, it goes to the selected class and gets it. The pane then grabs the text of the method and puts it on the display:

class TDEMethod:
    def get_text(self):
        return self.text
    ...

This all works fine, except for one minor problem. Sometimes we don’t have a selected class or a selected method. What can we do then?

The conventional answer in most development is to use null, nil, or None to represent the absence of something. And, it seems sensible enough. If you don’t have an object, you can’t really assign a object to a reference, so "null" seems like a reasonable choice. Let’s try that out:

class TDEClass:
    def get_current_method(self):
        return None
    ...

class TDEMethod:
    def get_text(self):
        return None
    ...

Now that we’ve done that, callers have a few more responsibilities. They have to check the return value of get_current_method and make sure it’s not None. If it isn’t they can take the returned object and call get_text on it, and if its return is not None, they can display the text. In other words, it’s just like a lot of the production code. You have to check the values returned by methods before you use them, and if there’s a problem you have to figure out what to do right then and there. It’s not uncommon to see methods that are completely dominated by checks of the return values from other methods. The resulting code is a real muddle.

It turns out, there’s a much better way to do this. We can create another class that looks just like TDEMethod except for one little detail. When you call get_text, it returns an empty string:

class NoMethod:
    def get_text(self):
        return ""
    ...

We can create an object of this NoMethod class and return it from TDEClass’s get_current_method method whenever a class doesn't have a selected method. The pane will go to the NoMethod object and call get_text just like it would for any TDEMethod. It just turns out that the this particular method object will always return an empty string, which is exactly what you’d expect to see on a pane if no method was selected.

You may have seen this pattern before. It’s typically called the Null Object Pattern, but I prefer Martin Fowler’s name: Special Case Pattern.

When you use Special Case you can take crufty special case logic and pull it out of your application, replacing it with a nice succinct use of polymorphism. That said, not everyone likes it. I remember creating a special case object with a coworker once and he said that he felt it was a lie. We had a collection of objects and there was one in it that represented the absence of something. He felt it was confusing, and it can be. Imagine going to that collection and asking it how many objects it contains. If the answer is 10 and some of them are special cases, the answer might not be what you are looking for. Like everything else in design, decisions are contextual. You have to weigh the use of the pattern and decide whether you can live with its tradeoffs in each situation. Personally, I prefer using Special Case most of the time just because I hate rampant null checking in programs.

Many of the elemental design patterns are identity tricks that use polymorphism. Composite allows you to believe you have a single object when, in fact, you have several. Proxy allows you to believe that you have a particular object when in fact, you have stand-in. Special Case allows you to believe that you have an object that is handling your messages in a typical way when in fact it could be doing nothing or handling an error condition with finesse.

You can find out more about the Special Case Pattern here and in Martin Fowler's book Patterns of Enterprise Application Architecture. Kevlin Henney's writeup of the Null Object Pattern is here (PDF).

Features Editor

layeringoverrides.png

Chris says: This blog is about structure and architecture (including Headway's structure101) - close to "beauty in the large". See Beautiful Structure, which concludes: "The bottom line is that structure and architecture are an intrinsic part of the code, and any discussion of code "beauty" without them isn't going to work for today's monster systems."

Thanks, Chris. Link

Features Editor

dijskra_archive.png

Andrew says: Check out the delightful Edsger W. Dijkstra Archives, maintained by the University of Texas. As one of the foremost computer scientists of his generation, Dijkstra argued that programming is more a branch of mathematics than engineering. The archive is largely a collection of his handwritten notes, and range from elegant geometrical proofs to a rant about his trip to Harvard Law School. One of my favorites is his withering Answers to questions from students of Software Engineering.

Thanks, Andrew. Link

Greg Wilson

As multicore CPUs and distributed applications become the norm rather than the exception, more and more programmers are discovering that concurrent programming is a lot harder than sequential programming---so much so, in fact, that traditional "hack and patch" approaches simply don't work. Race conditions and deadlocks are hellish hard to reproduce under controlled circumstances; if you don't design and analyze concurrent systems before putting them together, the odds are long that they'll never really work.

I therefore wasn't surprised that several of the contributors to Beautiful Code chose concurrency as their topic. While beauty is desirable elsewhere, I think it's essential in the brave new parallel world the industry is rushing toward. I'd therefore like to set a challenge to readers of this blog: we'll send a free copy of the book to the 20 people who submit the most elegant, correct, solution to the problem described below by this Halloween (October 31, 2007). Answers don't have to consist of running programs---sufficiently detailed pseudocode is fine---but you must explain (a) why you believe your solution works, and (b) what makes it beautiful. You can submit your entry at the Beautiful Code wiki site; the rules of the game are given there, and below.


Speed Scrabble is a game for two or more players that takes only a few minutes to play. The rules are simple:

  1. Spread the tiles face down on the table. Each player chooses 15 tiles at random, and puts them in front of herself; the rest are set aside.
  2. Someone says "Go!" Every player turns over 7 of her tiles and starts trying to make words with them. Words must crisscross in the standard Scrabble way, and the players' "boards" are independent---each player only uses her own characters.
  3. As soon as any player has made a board using all 7 of her characters, she shouts, "Go!" Every player turns over another character, so that all players now have 8 characters to use. Players may rearrange their pre-existing words when and as they please---they do not have to stick to their earlier choices.
  4. When any player has used all 8 of her characters, she shouts, "Go!", and everyone turns over their ninth tile. This repeats until everyone has turned over all 15 tiles. The winner is whoever makes a legal 15-character board first.

The challenge is to design the architecture of a "referee" program for a computer Speed Scrabble tournament. Contestants will submit classes that extend an abstract base class called IPlayScrabble that the contest organizers will provide. These classes will be loaded by a SpeedScrabble program, which will create an instance of each one and pass it the dictionary of words that can be used in the game, and its first seven tiles.

Each player will run in its own thread, in parallel with its competitors. As soon as it has made a board with the tiles it has, it will request another tile from the "referee". The first player to complete a 15-tile board wins.

This is trickier than it first seems because players have to be able handle "interrupts", i.e., notice when the referee is trying to give them another tile that they didn't ask for because some other player has taken the lead. (It's often the case that a set of $N$ tiles has no solution, but an $N+1$-tile extension does, so not taking tiles as soon as they're offered is a good way to come in last.) At the same time, when the central referee is handing out tiles, it must never wait for a player to accept one before moving on to the next player, because if it takes player P two seconds to say, "Yes, thank you, carry on," that's two seconds that player P+1 has lost.

So: how will the central referee hand out characters? What methods will you give players, and which ones will they be trusted to implement themselves? Most importantly, how will you convince sceptics that your synchronization and communication scheme can't deadlock, and won't ever starve one player because of something another player has done?

Features Editor

In this feature article, Ian Darwin (author of O'Reilly's Java Cookbook) provides examples of Java's beautiful Reflection API, which allows your code to reach down into the JVM and do some of the same things that the Java runtime does: discover and load class files, instantiate classes, discover and invoke constructors and methods, discover and set/get fields, and more. > continue reading
Greg Wilson

One of the reasons there's less beautiful code in the world than most of us would like is that academic computer scientists don't actually seem to care much about it. Other than a lecture or two about commenting and sensible variable names, they don't talk about it in class---certainly not as much as professors of architecture talk about the esthetics of their discipline---and most journal editors never even look at their contributors' code. The result is a vicious circle: people don't think other people care about beautiful code, so they don't talk about it, so everyone believes it isn't really important.

One welcome exception is John Wiley & Sons' journal Software: Practice & Experience. Now in its thirty-seventh year, SP&E has published everything from Bourne's "A Design for a Text Editor" and first description of Make to papers on efficient plagiarism detection for large code repositories and an empirical study of Java bytecodes.

One of my favorite SP&E papers from the past few years is Jing-Chao Chen's "Building a new sort function for a C library", from 2004 [1]. You might think that sorting (at least for data sets smaller than Google's) is a solved problem; if so, Chen's abstract is worth reading in full:

Up to now, the most efficient sort function for a C library was a variant of Hoare's Quicksort (qsort, for short), which was proposed by Bentley and Mcllroy in the early 1990s. Here we call this library function BM qsort. This paper introduces a library function which is based on Chen's Proportion Extend Sort (psort). This work is inspired by the fact that psort is generally faster than qsort, and in the worst case, qsort requires O(n2) comparisons, while psort requires O(n log n). In our library function, many tricks used in BM qsort have been adopted, such as sorting a small array by an insertion sort and the handling of equal elements. Some new tricks are also proposed, however, such as the adaptive partitioning scheme. To assess more effectively the behavior of our function, the test cases are enhanced. The empirical results show that our function is robust and faster than BM qsort. On particular classes of inputs, such as 'already sorted', it is linear time.

Chen' Proportion Extended Sort doesn't outperform Quicksort in big-Oh terms---nothing could---but over the course of eighteen pages, this paper shows how and why it does better in practical terms. It's a great example of how practitioners can learn from one another, and gradually improve on one another's work. It is also, once you understand it, some very elegant code.

[1] Jin-Chao Chen: "Building a new sort function for a C library". Software: Practice & Experience, 34:777-795, April 2004.

Alberto Savoia

You are a bright-eyed and bushy-tailed developer. You have just finished reading Beautiful Code and you are ready to create some beautiful code of your own. You can’t wait to put what you’ve learned into action. You fire up your IDE. As the blob of code that you’ve inherited and have to work with slowly loads, the brightness in your eyes is replaced by a glazed look. A minute later your bushy tail hangs limply in defeat. Reality sets in. Beautiful Code goes back on the shelf, next to Programming Pearls and Six-Pac Abs in Seven Days. You drink a sip of tepid coffee, sigh, and start hacking at the blob of code with the same level of energy and enthusiasm commonly displayed by those people in orange vests picking up litter on the side of the highway.

The two most common comments I’ve heard on the topic of beautiful code, following the release of the book, go something like this:

Comment 1:

“I have read a few chapters of Beautiful Code. It’s a great book, but in my job I have to maintain a ‘steaming pile of legacy code’. I don’t have many opportunities to think about beauty because I barely have time to keep the existing code functional. The best I can do it to keep crappy code from getting worse.”

Comment 2:

“Very interesting book. I wish I had an opportunity to think about cool algorithms for tough problems, but I am working on a boring enterprise application. I read stuff from a database, do something trivial to it and then I generate some reports. There aren’t that many opportunity for clever algorithms and beautiful solutions in business logic.”

It’s easy to sympathize with, and understand, both comments. The odds of finding truly beautiful code in most production systems seem to be on par with the odds of finding a well-read copy of IEEE Transactions on Software Engineering in Paris Hilton’s apartment. Furthermore, enterprise software, which represents the bulk of code in existence, deals mostly with forms, reports, etc., which – one might argue – seldom require much thinking or cleverness.

Let’s face it, the majority of code that has to be written does not offer chances for the kind of beauty and cleverness that would earn it an entry in Beautiful Code – Part II. For every opportunity to implement something cool and clever, like MapReduce (see Chapter 23), there are hundreds of blue-collar pieces of code that have to be written or maintained.

Does that mean that you should stop thinking about beautiful code in your day-to-day programming? Should you save those lofty ambitions for your after-hour pet projects – or abandon them altogether? Of course not!

The opportunities for creating a true masterpiece of coding worthy of sharing and bragging about may be rare, but you have dozens of chances everyday to make the code base you work with more beautiful – even if you are stuck working on a mortifying morass of legacy code. That’s what my series of blogs “Beautiful Code in the Real-World” will be all about.

In the next few days and weeks, I will use these blogs to share with you thoughts, strategies, and ideas for creating beauty in everyday production code – even if that code looks as if it fell off the ugly tree and hit every branch on the way down.

Make sure you come back for Part II – Scorn globally, act locally.

Michael Feathers

There’s one thing about software development that puzzles me more than anything else: talent. Some people just have it. They can crank out code and solve staggering problems, but they also have another ability which makes a huge difference. They know good design when they see it. They can tell very quickly whether a piece of code was developed thoughtfully or haphazardly; whether it’s trustworthy code or something that is ready to slide down the entropy well and deserves a good kick on the way down. They just know.

Maybe talent isn’t the right word. Maybe the right word is experience. Very experienced developers have this uncanny sense of design, but not all of them. I really don’t know whether it is learned through intense experience or fostered by innate ability but there definitely is something to it.

A long time ago, I read a book called Drawing On The Right Side of the Brain by Betty Edwards. The premise of the book is that artists see the world differently. They see things in a way which lends itself to the creation of art, and if you can mimic their mode of perception you can become more artistic.

One of the exercises in the book is to take a picture of someone’s face, turn it upside down, and then draw it. Amazingly this works very well. You are able to concentrate on curves and angles and see a face purely as shapes and textures. But, when the picture is right side up, we see it as a face and we confuse what we know about faces with what we actually see. It’s as if we have an internal monologue that goes “Oh, face. Faces are ovals; I’ll draw an oval. Hair is long and stringy; I’ll draw some lines.” But, when we get into that perceptual mode, the result is often cartoon-ish.

When I read Drawing On The Right Side of the Brain, I wondered whether there is something analogous that happens in software. Maybe very experienced designers just see things differently.

I was reminded of all of this a few years ago when another book came out, Blink by Malcolm Gladwell. In it, he argues that a lot of our cognition happens instantaneously and somewhat unconsciously. We can see this in the decision process (or lack thereof) used by experts. Often they just sort of know the answer, but they aren't quite sure how they arrived at it.

Experts can, of course, be wrong but I think that there is value in seeing things the way that an expert in a field might see them, and that if we accept the premise that arriving at better solutions is a function of being able to see them, then we have an opportunity to move design learning into a different direction. Maybe we can teach design sense or at least, design appreciation by bombarding people with examples.. here's a good snippet of code.. here's a bad one.. here's a good one.. here's a bad one.. Example after example until people grok the essence of good code.

I don't have any illusions that this sort of thing could be anything near a complete education. Some lessons have to be hard-won. Design is a deep skill, and there's no substitute for writing code and living with it for years. But, I have run into too many people who just really haven't encountered enough good code. They don't know what it looks like and they don't know why a particular piece of code is good or bad.

Next week at Agile2007, Emmanuel Gaillot and I will be hosting a workshop entitled Design Sense. We've gathered a large number of example code snippets. In the workshop, we are going to grade them and discuss them so we can learn more about what people see as good in design.. what they cue in upon. We're also interested in how much agreement there is in the community about goodness in design. If all goes well, the workshop could be the first step toward a teaching initiative that is focused on the use of these perceptual examples.

Michael Feathers

We can say that our discipline is young, but we can argue that is old also. It seems that each new generation of programmers rediscovers the past. We look at the current crop of languages and tools, and try to imagine something better and, if we have a bit of fire in us, we try to invent it but then we often find that someone else did it about 20 years ago as a research project.

This is especially true in the programming languages arena. It seems that every time someone starts down the path toward making a language simpler and more elegant, they end up at Lisp, Self, or one of the APL-ish languages. There's something elemental about those end points. We keep bumping into them.

A few years ago, I ran into something different. It was a demo of an environment called Subtext, developed by a researcher named Jonathan Edwards. Subtext is hard to describe because it contains so many ideas. One of them is that computing is more than just text. In Subtext, you edit in a larger structure, something akin to a spreadsheet. And, whenever you edit a part of your program the rest recalculates. This implies that your program contains visible example values, and that's true. The intent is to make your experience of your program immediate. You shouldn't have to guess at what your program does like you would in a purely text based language.

One of the other key ideas is that we've spent too much time vilifying cut/copy and paste in the industry. In Subtext, copy/paste is primary. In fact, it is the way that you construct programs. You copy and paste various little bits of them. The pieces you copy can maintain links to their original context; so sometimes, a copy is a bit like an extract method refactoring.

At this point, Subtext is demo, a very provocative demo, but it points in an interesting direction. There has a been a trend, recently, toward making IDEs more and more powerful. I know very few raw-Java developers these days, but I know plenty of Idea-Java programmers and Eclipse-Java programmers. These IDEs sand off the rough edges of the syntax and make Java into something else. Perhaps we need to think about how to design languages so that they are deeply amenable to IDE usage. Perhaps the future of languages is in environments like these.

Check out the Subtext demo. It's radical, but after watching it, I'm eager to see people attempt little parts of its agenda in the next generation of IDEs and languages, especially the visible example portion.

Alberto Savoia

My chapter in Beautiful Code is called "Beautiful Tests". In the chapter, I focus on a specific example of how a developer can use tests to make the code not only more robust, but also more beautiful.

I really enjoyed sharing my thoughts, and thought-processes, on developer testing using lots of actual code on a very specific example. But, as I was writing this chapter, I kept feeling a strong urge to also write something at a higher-level; something a bit more general and philosophical, to complement it.

The result is The Way of Testivus - Less Unit Testing Dogma, More Unit Testing Karma, a small booklet with twelve epigrams that summarize my philosophy on developer/unit testing.

Below are two of the epigrams; if you want to read more you can download the entire "The Way of Testivus" booklet.

If you write code, write tests

The pupil asked the master programmer:

“When can I stop writing tests?”

The master answered:

“When you stop writing code.”

The pupil asked:

“When do I stop writing code?”

The master answered:

“When you become a manager.”

The pupil trembled and asked:

“When do I become a manager?”

The master answered:

“When you stop writing tests.”

The pupil rushed to write some tests. He left skid marks.


Think of code and test as one

When writing the code, think of the test.

When writing the test, think of the code.

When you think of code and test as one,

testing is easy and code is beautiful.


Bruce Stewart

Simon Peyton-Jones, author of the "Beautiful Concurrency" chapter, presented this well received Haskell tutorial at OSCON.

Update: This tutorial is split up into two videos, the second part is here.

(Thanks, Brian!)