Wednesday, April 11, 2012

The olfactory quality of our language

Our language influences what we think, and our thoughts (or attitudes) sometimes guide our choice of words. And as with many things in life, some choices may look good in the beginning, even gain widespread application, but then become questionable on reflection.

One such choice is the term code smell, which typically refers to a code passage that cries out to be refactored, 'cleaned up'.

It's a very cleverly coined term. It associates certain patterns of bad coding (bad, because they make code less clear or more difficult to maintain, extend, or change) with a nasty experience that we all know. The analogy goes even deeper: bad smells in real life, once you have noticed them, are hard to ignore, and usually we have some impulse to do something about them, to eliminate the source of the stink. Likewise a 'code smell' is supposed to trigger action: reworking the code, cleaning up. Nowadays, every programmer knows what a code smell is; that is, everyone understands the notion, even if not necessarily everyone at all times recognizes typical smells when they encounter them — or at any rate, not necessarily all smells are in fact cleaned up. (At least that's what I often see in practice.) But everyone at least understands the idea of what a code smell is.

Cool, so what's the catch?

In a paper a few years ago, Kent Beck has written about "the engineer’s approach to change: find a problem, solve it"[1]. This way of going through the world and looking at things, however, "is biased negatively and it ignores whatever is going well". As Kent writes, this negativity will drain your emotional energy, if you make it into a general approach to thinking about what to do next. In effect, it will make it harder to achieve change. "Change is not aided by the dominant engineering problem/solution metaphor, where the world is seen in terms of problems to be solved."

Now, these insightful words were written about change, that is, about modifying the way we work, for instance when we start adopting the XP practices. What I want to suggest is that they equally apply to 'normal working mode'. When we are in the middle of everyday coding, we're also in danger of getting into a problem-response mode of acting. And when we're using words like 'smells' to describe to ourselves what we are doing, we cement this way of looking at things. (The effect is compounded when we use it in conversation, face-to-face or digitally, with other developers.)

When you are coding, what habitual attitude do you have towards the code base on which you are working? Do you think of it in terms of 'problems' (to be solved), or in a more strongly, colorful language, in terms of 'smells' (to be cleaned up)? Observe yourself during an average day of coding; make a list on a sheet of paper: how often do you change production code, and what exactly is it about that code which triggers action? How do you think and feel about it? The difference here may be subtle, but compare "Hey, these two passage look as if we can generalize and have a single, elegant query object!" with "Damn, there's this stinking code duplication again, I have to eliminate this!" It doesn't just feel bad when you recognize the pattern (in this case, a code duplication) in the code and instinctively classify it as 'smell'. There's also not much satisfaction to be gained after you have acted and changed the code. You've just changed a 'bad thing' to an 'ok thing'. Moreover, this kind of situation is likely to happen repeatedly, all over the day. Thus we establish for ourselves a feedback loop very effective in creating a general mood of frustration day after day.

So, we might have second thoughts about an outlook, sedimented in terminology, that encourages us to reduce stimulus-response patterns to problem-response patterns. (To be sure, even looking at things in terms of stimulus-response is a narrow mindset. But we're making it even more narrow by favoring a notion of triggers to action that is negative.) Such an outlook is very much suggested by speaking of 'smells'.

To widen our perspective: the notion of a 'code smell' is not the only notion that works this way (though it's probably one of the most ingrained). Generally, becoming more aware of the language we use when we think about what we do in our daily work pays off — even if it's just a small step that brings some fresh air and lets us look at a code base without a continuously crooked nose.



  1. Yes, I think small difference in the way you think can have huge effects. So focusing on the elegance of the result instead of the bad smell of the original code sounds great.

    Is the word "smell" originally really that negatively annotated? Maybe you just automatically think of "bad smell" because literature about "code smell" focuses on the negative view so much? You could just think of your refactoring as changing the "code smell" from suboptimal cases that come naturally into a very pleasurable scent :)

  2. Thanks for your feedback.

    I think you may be right with respect to the general English term; it might not be that heavily connotated with negativity. Then the more specifically we look at software literature, it relies much more on the negative force.

    The book from which I, personally, picked it up ten years or so ago was Martin Fowler's 'Refactoring' (which I still think is excellent, and one of the most deeply shaping influences for me personally in my early developer's life). There's a chapter about 'Bad smells in code' (written together with Kent Beck) that clearly makes the association, and also gives a direct statement of the problem-solution mindset. It says that describing smells will "give you indications that there is trouble that can be solved by a refatoring" (75). Again, I think it's an ingeniously chosen term. It does have this negative thrust, though.