Quote of the week – hard things

There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.

Phil Karlton

I have seen a number of variations on this quote, and it looks as though the original quote only included two of the three hard things. Martin Fowler quotes Phil Karlton here and there is more discussion of the quote here.

I don’t know whether the original quote concerned hardware caching or software caching. Since I’m not a hardware engineer, I’ll talk about software caching. When implementing software caches I have found it useful to apply the Single Responsibility Principle and divide things up along these lines:

  • The thing that calculates (fetches, obtains, looks up etc.) the value we want.
  • The thing that actually stores the cached value.
  • The thing that decides whether the value should be cached or not.
  • The thing that decides whether the cache (or a given cache entry) should be invalidated.

I wish I were better at naming things. Naming is important, good naming can show that similar things are connected and dissimilar things are separate. Good names can show patterns in the code that are otherwise difficult to see. When we’re trying to get acquainted with a new codebase, names can make make our lives heaven or hell.

It isn’t always easy to work out what “similar” means. In this comment on my tbb::concurrent_vector post, Adrian points out that std::vector guarantees contiguous storage whereas tbb::concurrent_vector doesn’t. What are the essential properties of a vector that must be maintained by anything calling itself a vector? The lack of contiguous storage in tbb::concurrent_vector hadn’t occurred to me as being noteworthy – hence I wrote a blog post that was confusing. Having a name that makes sense to you is one thing, having someone else look at it helps identify any assumptions you’ve made that you didn’t know you were making.

There is a particular joy in coming up with a good name. On the odd occasions I experience this joy it is usually because I have forgotten (in the sense of rote learning) the name of something but I’ve been able to reconstruct what the name is. At the very least it shows some consistency – my brain is working the same way now as it was when I originally came up with the name. Sometimes the quality of a name doesn’t come to light until we try and name something that’s similar – if the original name is good, we can easily derive a name for the new, similar, thing.

I am sure that off by one errors will always be with us. The half open ranges used by many languages (including C and C++) make the situation better, but not perfect. My first job was programming in FORTRAN 77 where arrays start at index 1. I had to write more +1 and -1 statements in FORTRAN than I have ever had to in C and C++. Even better was when we were calling between C and FORTRAN. Yes, we knew the array indices were off by one, but it wasn’t always easy to remember whether it was +1 or -1.

I have mentioned this piece by Dijkstra before. As well as his theoretical analysis, he also mentions that the programming language Mesa allowed for all four different range conventions, and that the “half-open, start at zero” convention led to fewer errors.

Quote of the week – quality

… I am convinced that the quality of the product can never be established afterwards. Whether the correctness of a piece of software can be guaranteed or not depends greatly on the structure of the thing made. This means that the ability to convince users, or yourself, that the product is good, is closely intertwined with the design process itself.

Edsger Dijkstra

We don’t get quality by having a week, or even a two or four week, “quality sprint” at the end. We don’t get quality by just talking about quality. We don’t get quality by putting up motivational posters (although we did get a lot of laughs out of the wonderfully cynical graffiti that was added within 24 hours of their appearance).

We get quality by wanting it and engineering for it and caring about it at every stage in the process. We get quality by being prepared to admit that we’re doing something (or everything) wrong and finding a way to do it better. Quality software is bloody difficult to obtain even when we care about it deeply, follow all the industry best practices and invent a few best practices of our own. Quality software is impossible to obtain if we’re not doing everything we possibly can.

Dijkstra talks about the “ability to convince users, or yourself, that the product is good”. One of my first questions to a team is “does your software work”? The vast majority of teams will answer “yes”. Some of them might admit to a qualified “yes”. The next question is “how do you know your software works”? The answer to that question should be wide and deep. It should encompass testing of many flavours – unit, automated, user, white box, black box, integration, system. It should encompass development practices, communication structures, requirements gathering, change management and the attitude of everyone on the team.

The best team I was ever on had a white box QE who looked at every decision with a testing and quality mindset. Whenever we came up with a design for a component he asked how it was going to be tested, how we would know whether it worked or not (the definition of “works” can be surprisingly subtle) and what additional integration tests would be necessary because that component interacted with other components. There were times where that QE was the least popular person in the room. These were also the times when it was incredibly important to keep him in the room and make sure we were all listening to him. That in turn demanded a certain attitude from the rest of us.

Quote of the week – the org. chart

Don’t ship the org. chart

Steve Sinofsky

Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. (For example, if you have four groups working on a compiler, you’ll get a 4-pass compiler)

Conway’s Law

If you want a product with certain characteristics, you must ensure that the team has those characteristics before the product’s development.

Jim McCarthy and Michele McCarthy – Software for your Head

Remember Sinofsky’s “don’t ship the org chart”? It is a lie. You cannot avoid it. You always ship the org chart. So the real question is, what is the org. going to look like so that we ship something good-looking? That’s the real purpose of Steve’s rant. No matter how much politicking or boosting you do for this important service-oriented architecture, it doesn’t work unless you have a service-oriented org chart. And Google does not, apparently.

Unknown Amazon engineer on Hacker News

There are many more variations on “don’t ship the org. chart”. The quote I find interesting is the one from the anonymous Amazon engineer who takes a different approach – you will ship the org. chart, so make sure that the org. chart is the one you want to ship.

“Steve’s rant” refers to this post by Steve Yegge. I have never been sure how seriously I should take Steve Yegge’s claim that it was posted accidentally, but it’s a great read.