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

Recent Posts

Michael Feathers

Many people are dabbling in functional programming these days. Haskell is more popular than it ever has been, OCaml has it's adherents, and we are starting to see common functional idioms spread throughout the industry.

Why am I not happy?

Here's why. I think that most functional programming languages are fundamentally broken with respect to the software lifecycle. I realize that's a bold statement. Let me back it up.

Imagine these lines of code in any object-oriented language (I'll use Java here because it is familiar to most people, even if they dislike it):

public class X {
    public void method() {
       ...
       badMethod();
       ...
    }
    ...
}

Class X has a method named badMethod. The method isn't bad because it does something awful while the system is running; it's bad because it does something painful during testing. It could be anything. The method could make a call to our production database and update it, or it could communicate with another system across a socket. It could even touch some low level hardware that causes a mechanical machine arm to do something that it shouldn't be doing over and over again while we are testing.

In an ideal world, people would design their systems so that classes and clusters of classes could be tested independently; the industry is slowly rediscovering the utility of unit testing. But, stuff happens. People make mistakes. They think that they've got it all under control until they discover that they have a big wad of code that they can't easily change and don't understand. At that point, they wish that they could write little tests that help them understand what the hell their code does before and after they change it.

The nice thing, so far, is that most of the object-oriented languages out there leave you an “out.” You can use the features that were built in to provide flexibility to give yourself enough maneuverability to test. In short, we can do this:

public class TestableX extends X {
    void badMethod() {
        // do nothing
    }
}

We can override functionality and build ourselves a wedge that makes testing easy.

The fact that badMethod is a non-final, override-able method makes it something I call a seam. A seam is a place where you can substitute one piece of functionality for another without editing. Most languages provide seams. The C programming language is rich with them. You can use the preprocessor, function pointers, and link substitution to replace awkward functionality during testing, but it isn't quite as easy as it is in OO.

Virtual function calls in OO languages are a common seam. Java is easy. C++ is a bit more awkward. Ruby and Python are a breeze. The power of these seams is in the fact that you can get between around around the pieces of your application when testing. It isn't just a big hard-coded mass.

What about Haskell, OCaml, and Erlang?

Yes, you can provide alternative modules to link against, but it's clunky. Sure, you can use virtual in OCaml, but who really organizes all of their OCaml code in classes?

Haskell is a bit nicer, most of the code that you'd ever want to avoid in a test can be sequestered in a monad, and I expect that half of the Haskellers reading this will argue that functional purity obviates any need to unit test; it can all be done in QuickCheck. I hear you, but there's distance between here and there and that distance can be a quagmire.

No, the fact is, the late-binding that OO languages provide makes code written in them more easily recoverable. And, this is important because entropy happens. Count on it.

Andy Oram

It's hard to remember to do simple code inspections--the oldest quality technique in the software field--amid the welter of graphical tools, measurement tools, and other fancy tricks the industry has thought up. Code inspections make sense. If you find a flaw during a program run and debug it, you've fixed just one bug. Only a code inspection can fix the potentially hundreds of other similar bugs.

But code inspections are a headache, because logic and consistency are hard to determine. Miska Hiltunen is trying to make them more agreeable by rigidly limiting what you have to look for, and assuring developers that they can get through each inspection in just about an hour. > continue reading

Andy Oram

The Association for Computing Machinery has given it\s highly prestigious A.M. Turing Award to the researchers credited for inventing Model Checking: Edmund M. Clarke, E. Allen Emerson, and Joseph Sifakis. > continue reading

Michael Feathers

Last week, Paul Graham released his first version of Arc.

It's made a noisy splash.

If you haven't been following Arc, here's the story in a nutshell. Paul Graham is an entrepreneur, Lisp hacker, and essayist. Years ago, he founded a startup (viaweb) which created what was later known as YahooStores. YahooStores was one of the first full-fledged web apps, and it was also written top to bottom in Lisp. His team considered Lisp their secret weapon. By all evidence, it was:

"When one of the customer support people came to me with a report of a bug in the editor, I would load the code into the Lisp interpreter and log into the user's account. If I was able to reproduce the bug I'd get an actual break loop, telling me exactly what was going wrong. Often I could fix the code and release a fix right away. And when I say right away, I mean while the user was still on the phone.

Such fast turnaround on bug fixes put us into an impossibly tempting position. If we could catch and fix a bug while the user was still on the phone, it was very tempting for us to give the user the impression that they were imagining it. And so we sometimes (to their delight) had the customer support people tell the user to just try logging in again and see if they still had the problem. And of course when the user logged back in they'd get the newly released version of the software with the bug fixed, and everything would work fine. I realize this was a bit sneaky of us, but it was also a lot of fun."

- Paul Graham

Makes you nostalgic for the pre-Sarbanes Oxley era doesn't it?

Anyway, Paul Graham wrote an essay a few years ago describing his plans for a 100 year language. He wanted to make something powerful and beautiful; something that would last, and he wanted to use early Lisp as a base. Arc is that language and it's not quite what people expected.

What's the problem? Well, people were expecting something spectacular. They were expecting new language features that would knock their socks off. But, Arc isn't that language. It is, instead, a very clean deliberately designed, close to the roots Lisp.

I don't know enough Lisp to be able to judge his efforts. I, like many other people, have had just enough Lisp in school to fumble with the parens while writing a maze solving program or an Eliza. I've never used it in production code but I've always wished that I had. The thing I like about Graham's Arc initiative is its philosophy.

Graham is a minimalist. He likes a language with a small core. He's also trying to a take a simple principle: brevity is power and push it extremely hard on a road (Lisp) that is already well worn.

Frankly, you probably couldn't pick a more thankless approach. Once people feel that they know something, it's hard for them take efforts to tweak the fundamentals seriously. But, it is serious work. The tweaks may not look all that special individually, but they they may well be. Practice will tell.

All I know is that I wish there were more people doing this sort of work. I've had some brushes with language design and I'm a minimalist also. I used to joke with friends that when your aim is build a language with a simple core, one that you can build everything else upon, you end up in one of two places: McCarthy's Lisp or Self.

I wonder now, whether it is really true. Maybe those languages aren't natural asymptotes. Maybe language designers are sucked toward them by familiarity or dissuaded from the space around them by people who've been there and done that.

The minimalist language space could be more fertile than we suspect.

I hope that it is.

Michael Feathers

Recently, Greg Weber blogged about a Haskell version of the regex matcher that Brian Kernighan wrote about in Beautiful Code.

The example is written in C. I wondered if a more beautiful version could be created using a newer programming language. Kernighan points out that it takes more code to produce the equivalent in Java, which is not suprising. But he also points to the strengths of C. “Pointers … are used to create compact expressions that naturally express the extracting of individual characters and advancing to the next character. Array indexing of substrings can achieve the same effect, but in this code, pointers do a better job …” But we can maintatin the advantages of pointers and work at a slightly higher level by using lists. Since this code also uses recursion and pattern matching, Haskell is a very natural replacement.

It's very nice looking code