Taavi's Blog


Beautiful, terse code

2011-04-19T15:10:00-0400 | categories: programming

I recently read Revisiting "Tricky When You Least Expect It" and it reminded me of the last chapter in Beautiful Code ("Writing Programs For “The Book”", p539) and of my own experience trying to refine the code describing a job spreader.

In all three cases, there was a simple, intuitive model for how to calculate a thing (or how to move data around). However, I've noticed with the simplest, most straightforward answers tend not to tell a story because they get right to the point.

I think there's something to be said for telling a story, even if it makes things more verbose, but at some point you just need to express a computation. The question is: at what level do you do that? Naturally, context matters a lot. So what's our context?

For these three examples, the context is something so small, that once you've written it at this lowest level, it doens't make sense to break it apart any more. You can understand what it does from its public behaviour, and if you need to know exactly how it does that, you'll have to read the code and really understand why it's implemented that way. Going to why is a different level of abstraction from what. It's why we write comments (which are obviously missing from the examples below).

A while ago when I started reading about TDD and modern unit-testing, I thought there should be a test for every method, public AND private on a class. Testing the privates naturally involves subclass stubs or mocks (or in Python, just ignoring the underscores), and it did seem a bit of work. A co-worker pointed out that you really shouldn't need to test the internals, unless they're actually that complicated…and if they're that complicated, why aren't they part of some other class' public interface?

So I feel this tension between writing things with good obvious names and descriptions (like the high-level picture of the job spreader) directly as code, versus the example below which has so few moving parts that it doesn't make sense to unit test anything smaller than the entire method (assuming that the Python library is sufficiently tested). But you really have to sit and think about the smaller end.

And maybe this whole discussion is for naught because we should just comment these opaque gems. But at some point, someone will still want to understand the mechanics, and that will take a lot more thought.

1
2
angle_diff(Begin, End) ->
   (End - Begin + 540) rem 360 - 180.
Example smallest angle difference function from Revisiting "Tricky When You Least Expect It"
1
2
3
(defun area-collinear (px py qx qy rx ry)
  (= (* (- px rx) (- qy ry))
     (* (- qx rx) (- py ry))))
Example co-linearity function from Beautiful Code, p549
1
2
3
4
5
6
7
8
9
from itertools import chain, ifilter, izip_longest
def spreader_generator(blockpool, spread):
    sentinel = object()
    blockpool_iter = iter(blockpool)
    feeders = [chain.from_iterable(blockpool_iter) for _ in range(spread)]
    stripes = izip_longest(*feeders, fillvalue=sentinel)
    flattened_spread = chain.from_iterable(stripes)
    not_sentinel = lambda x: x is not sentinel
    return ifilter(not_sentinel, flattened_spread)
Example job spreader