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

Recent Posts

Michael Feathers

Lambdas and closures have just been voted into C++ 0x. Since this is a blog about beautiful code, I invite you to reflect on the relative beauty of a couple of code examples that were part of the lambda proposal.

Before lambda functions:


  class between {
    double low, high;
  public:
    between(double l, double u) : low(l), high(u) {}
    bool operator()(const employee& e) {
      return e.salary() >= low && e.salary() < high;
    }
  };




  double min_salary;
  ...
  std::find_if(employees.begin(), employees.end(),
                     between(min_salary, 1.1 * min_salary));

And now with a lambda function:

  double min_salary = ....
  ...
  double u_limit = 1.1 * min_salary;
  std::find_if(employees.begin(), employees.end(),
      [&](const employee& e) 
          { return e.salary() >= min_salary && e.salary() < u_limit;});

I suspect I'm not alone in liking the first find_if call better.

Here's the problem. When you use lambda functions, in any language, there is a tension between clutter and expressiveness. And, in fact, the person who wrote that example seems to have been aware of the tension. He introduced an explaining temporary variable u_limit in the lambda version, just to keep the clutter down.

This tension between clutter and expressiveness is unavoidable. The other day, I went back and forth between doing this in Haskell:

  signature :: String -> String
  signature = filter (\x -> elem x "{;}")  

and this:

  isSigChar :: Char -> Bool
  isSigChar = flip elem "{;}"

  signature :: String -> String
  signature filter isSigChar

I ended up choosing the first version - the lambda function version. But, Haskell helped me in that choice. It was a win because Haskell's syntax is relatively uncluttered.

Compare this again to the C++ example:

  std::find_if(employees.begin(), employees.end(),
      [&](const employee& e) 
          { return e.salary() >= min_salary && e.salary() < u_limit;});

The lambda in this example has a lot of noise. It has type declarations, and nearly more punctuation than text. The native clutter in C++ shifts the bar in the clutter versus expressiveness tradeoff.

I hope that C++ 0x programmers in exactly this situation will opt for the function object approach, but I suspect that they won't. Function objects are more painful to write. I suspect that, in the end, we'll see gnarlier calls peppering our C++.

Sadly, we've been on the slippery slope for a while already. I understand why, for instance, STL algorithms accept two iterators but it seems odd that there are no versions which enable simple forward iteration over a single container - just pass the container and go. Some teams write little adapter templates, but in most of the industry we have code all over the place which starts like this: find_if(employees.begin(), employees.end(), ...

Calls should be clean.

No, I have no doubt that people will find decent ways to use lambdas in C++, but they are going to have to stretch. This particular example highlights an important issue. The default clutter of a syntax matters. In another language, I'd probably use a lambda but in C++ I prefer this call:

  std::find_if(employees.begin(), employees.end(),
                    between(min_salary, 1.1 * min_salary));

It just reads better.

Michael Feathers

I know your code is copyrighted.

I'm not an expert in US Copyright law, but I do know that you don't have to register a copyright to have one. All you have to do is make some utterance on your behalf or someone else's and it's owned. Write code in a file - it's owned.

Why, then, do we have copyright notices in file headers? If you want evidence of plagiarism or illicit copying, you can diff files. Court cases have turned on that sort of evidence. No, it seems that a copyright notice in a file is a warning. And, at the very least, it does indicate an owner - it tells you whose file it is. But.. why do the notices have to be so long?

Source file headers bother me, not in principle, but because people rarely know when to stop. First you have the copyright notice, then you have the disclaimers of liability, and if you are really unfortunate, you have 50 to 1000 lines of version control comments. You know, that's what we have version control systems for - to keep all of that history. There isn't much value in keeping it in the code. It's not like a file is going to wander down to the corner on its own. Code lives in an eco-system. I dare anyone to take a random file from a "enterprise" project and attempt to use it independently. It just doesn't work like that.

For better or worse, files are seen as the smallest independently distributable units in software. I suppose that if you are a lawyer, you take notice of that fact and make the file the unit of diligence. You want the notice there so that it is plain and in the face of the the potential abuser. And, if a legal notice is small, that's fine. One line, two lines.. I can handle that. The thing that I want an alternative to is the mandatory page down on open that is part and parcel of most source code. It's a tax. It is (to draw an analogy) as if every car manufacturer put a reverse etched liability disclaimer in the windshields of cars - something that you as a driver can't avoid every time you sit down in the car.

Do we really need that? I don't think so, but I do know that in most organizations, no one wants to be the one who trimmed back the mandatory header. It's just too easy to avoid that decision.. it's too easy to not be he person who said "You know, I think we can make do with a single line copyright statement and a url to our legal notices." It's such a small inconsequential issue.. unless you're a programmer.

If you're a programmer you scroll, and scroll, and scroll.

Note: this blog was inspired by a hard-edged code review done by a few years ago at a client site by "Uncle Bob" Martin.
Michael Feathers

The other day, I was thinking about some code in a domain that I used to do a lot of work in: signal filtering. Imagine that you have an array of doubles and you want to remove some of its spikiness. One way to handle this is to use a low pass filter. You take your old array and transform it into a new one in which each element array[i] has the value (old_array[i-1] + 2 * old_array[i] + old_array[i + 1]) / 4.0. The code for that filter is straightforward except for the fact that you have to deal with the edge cases: the calculations for i = 0 and i = n - 1 are a little different. All in all, it's about five to seven lines of code, depending upon how you format it.

For kicks, I decided to write it in Haskell. If I'm clever enough, I thought, I should be able to write the code without any edge conditions. I can create a lazy list that goes beyond the edges and then pick out the subset that I need from the center.. the values in the range 0..n-1.

I ended up with a solution but it wasn't pleasant, so I posted it to the Haskell Cafe mailing list. A guy who knows much more Haskell than I do pulled an edge case back in and came up with this shorter solution:

smooth n = (!! n) . iterate f where
  f ds = [(x + 2 * y + g y z) / 4.0 | x:y:z <- tails (head ds : ds)]
  g x []    = x
  g _ (x:_) = x

The function smooth allows you to smooth a list n times. It does this by creating an infinite list of iterative applications of a low pass filter and selecting the nth element of that list. The function that is iterated, f, constructs a list of elements which are applications of the filter (x[i-1] + * 2.0 x[i] + x[i+1] / 4.0). The smooth function also uses a list comprehension that matches triples based upon the staggered tails of a the original list. The special case at the far end of the list is handled by a function, g, which takes an element and a list and returns the appropriate values at the edge for the filter.

Simple, right?

It depends on your perspective, I guess. There is some simplicity there if you think in those terms.

To me, this problem seems emblematic of the difference between imperative and functional programming. In functional programming, some solutions are very natural when seen from the imperative mindset, but others aren't - you have you go around the block to get next door. Functional programming has a grain to it and the grain makes particular classes of solutions much more natural even though they appear alien when seen from other contexts.

I guess this is true of all styles of programming. There certainly are some problems that are difficult in an imperative style. The thing that I find interesting about the pure functional style, though, is that it pushes you toward its own set of abstractions. The function tails in the code above is a good example. If you give tails this list: [1,2,3] it gives you this list back: [[1,2,3],[2,3],[3],[]]. I doubt many people using a non-functional language could imagine many uses for a function like that, but when the grain runs toward laziness and away from mutation, you reach for these sorts of abstractions for leverage - they become your bread and butter.

Haskell truly is a different language. It makes most other programming languages look like dialects of each other.

Michael Feathers

I'm at the airport, coming home from one of my favorite conferences: Software Practice Advancement. It is a conference but it is also a yearly hangout for a group of people who have a terrifying amount of insight and experience. Many of them are from London, so you get to hear about all of the incredible things that happen in bank projects. That may sound mundane, but it isn't. I don't think there's a domain quite like it now. It mixes high end mathematics, a business interface, incredible time pressure and enormous processing constraints.

This year, I did a session with Steve Freeman and Meirion Morgan called Functional Finance. It was, essentially, and introduction to OCaml using examples from Quantitative Analysis. I don't really know much about quantitative analysis, but I was able to do the intro to OCaml bit for the session. All in all, it was fun, but one of the most interesting things to me, was the last piece of preparation that we did.

Before the conference, I went to Steve's house and we sat down to work on the last example. It was a bear. It contained a triply nested loop on a single array, whose inner loop iterated backwards while performing an accumulating calculation on the current and previous element. We tried to imagine what combination of maps and folds we would need to make the code more functional.

I wasn't much help as I was jetlagged, but Steve attacked the example viciously. One of the things that he did was very interesting. He noticed that the inner loop contained special case logic for the beginning of the array, and that the special case logic could go away if the array was extended leftward.. if it, in effect, had a -1 index. I'd seen and done this sort of thing before, but it occurred to me that I'd never seen it written up. It's a very handy technique. Special cases can often be eliminated if you extend the edges of collections.

For a more concrete example, imagine a program that scores a bowling game. We all know that bowling games have ten frames, but the rules of bowling allow a variable number of throws per frame. If you throw a strike, you have only one throw for that frame but the score for that frame is 10 plus the sum of the next two throws. It seems like this is simple enough logic to code, but the tenth frame is special. A strike in the tenth frame, again, wants two more throws. Does this mean that we should use a data structure which can have three possible throws per frame? We could do that, but we could also have a dummy eleventh frame hanging off the end of the array which the tenth frame can dip into when calculating its score. Then, the logic for scoring is uniform. A frame's score is the sum of its throws, except in the case of spares and strikes which both use throws from the next frame to calculate their own score.

The pattern shows up quite a bit in games. The game Conway's Life is a good example. Cells are alive in the next generation if the sum of their neighbors is within a set of constraints. Cells on the edge of the playing field don't have as many neighbors as cells that are not on the edge, but you can fix that by extending the edge one cell in each direction. You can calculate for cells that are between (1,1) and (n-1,n-1), and allow their calculations to use values in the range (0,0) to (n,n). It's an easy way to code Conway's Life if you decide not to do something more ambitious with the edges like wrapping them around.

Edge Extension is a nice technique, but it does have trade-offs. For one thing, special case logic is a bit more explicit than Edge Extension. If you are working on something like the bowling game, something which models a real world process, you'll probably find yourself documenting the differences between your code and the normal understanding of the domain. But, on the other hand, special case logic is often nasty, complex, and error prone. If we can get rid of it, we're often better off.

Andy Oram

Beautiful Code won Dr. Dobbs Journal's JOLT award as the best general book of the year in computing at SD West earlier this month. JOLT awards are some of the most prestigious in the field of software engineering. Details in our publicist's blog.