How to De-Brilliant Your Code
Three weeks, three reader questions. I daresay that I’m on a roll. This week’s question asks about what I’ll refer to as “how to de-brilliant your code.” It was a response to this post, in which I offered the idea of a distinction between maintainable code and common code. The lead-in premise was that of supposedly “brilliant” code, which was code that was written by an ostensible genius and that no one but said genius could understand. (My argument was/is that this is usually just bad code written by a self-important expert beginner).
The question is, as follows, verbatim.
In your opinion, what is the best approach to identify que “brilliant” ones with hard code, to later work on turn brilliant to common?
Would be code review the best? Pair programming (seniors could felt challenged…)?
Now, please forgive me if I get this wrong, but because of the use of “que” where an English speaker might say “which”, I’m going to infer that the question submitter speaks Spanish as a first language. I believe the question is asking after the best way to identify and remediate pockets of ‘brilliant’ code. But, because of the ambiguity of “ones” it could also be asking about identifying humans that tend to write ‘brilliant’. Because of this, I’ll just go ahead and address both.
Find the Brilliant Code
First up is identifying brilliant code, which shouldn’t be terribly hard. You could gather a quorum of your team together and see if there are pockets of code that no one really understands, or else you could remove the anchoring bias of being in a group by having everyone assess the code independently. In either case, a bunch of “uh, I don’t get it” probably indicates ‘brilliant’ code. The group aspect of this also serves (probably) to prevent against an individual not understanding simply by virtue of being too much of a language novice (“what’s that ++ after the i variable,” for instance, indicates the problem is with the beholder rather than the original developer).
But, even better, ask people to take turns explaining what methods do. If people flounder or if they disagree, then they obviously don’t get it, self-reporting notwithstanding. And having team members not understanding pockets of code is an ipso facto problem.
An interesting side note at this point is whether this illegible code is “brilliant” or “utter spaghetti” is going to depend a lot more on knowledge of who wrote it than anything else. “Oh, Alice wrote that — it’s probably just too sophisticated for our dull brains. Oh, wait, you were reading the wrong commit, and it’s actually Bob’s code? Bob’s an idiot — that’s just bad code.”
De-Brilliant The Codebase
Having identified the target code for de-brillianting, flag it somewhere for refactoring: Jira, TFS, that spreadsheet your team uses, whatever. Just make a note and queue it as work — don’t just dive in and start mucking around in production code, unless that’s a team norm and you have heavy test coverage. Absent these things, you’re creating risk without buy in.
Leave these things in the backlog for prioritization on the “eventually” pile, but with one caveat. If you need to be touching that code for some other reason, employ the boy-scout rule and de-brilliant it, as long as you’re already in there. First, though, put some characterization tests around it, so that you have a chance to know if you’re breaking anything. Then, do what you need to and make the code easy to read; when you’re done, the same, “tell me what this does” should be easy to answer for your teammates.
De-brillianting the codebase is something that you’ll have to chip away at over the course of time.
De-Brilliant The Humans
I would include a blurb on how to find the humans, but that should be pretty straightforward — find the brilliant code and look at the commit history. You might even be able to tell simply from behavior. People that talk about using 4 design patterns on a feature or cramming 12 statements into a loop condition are prime candidates.
The trick isn’t in finding these folks, but in convincing them to stop it. And that is both simple to understand and hard to do.
During my undergrad CS major many years ago, I took an intro course in C++. At one point, we had to do a series of pretty mundane, review exercises that would be graded automatically by a program (easy things like “write a for loop”). Not exactly the stuff dreams are made of, so some people got creative. One kid removed literally every piece of white space from his program, and another made some kind of art with indentations. When people are bored, they seek clever things to do, and the result is ‘brilliant’ code.
The key to de-brillianting thus lies in presenting them with the right challenge, often via constraints or restrictions of some kind. They do it to themselves otherwise — “I’ll write this feature without using the if keyword anywhere!”
The Right Motivation
Like I said, a simple solution does not necessarily imply an easy solution. How does one challenge others into writing the kind of straightforward code that is readable and maintainable?
Code review/pairing presents a possible solution. Given the earlier, “can others articulate what this does” metric, the team can challenge programmer-Einstein to channel that towering intellect toward this purpose. That may work for some, but other brilliant programmers might not consider that to be a worthwhile or interesting challenge.
In that case, automated feedback through static analysis might do the trick. FXCop, NDepend, SonarQube, and others can be installed and configured to steer things in the general direction of readability. Writing code that complies with all warning thresholds of such tools actually presents quite a challenge, since so much of programming is about trade-offs. Now, a sufficiently determined clever coder could still invent ways to write hard-to-read code, but that would be a much more difficult task when he’d get slapped by the tool for chaining 20 Linq statements onto a single line or whatever.
Of course, probably the best solution is to work with the sort of people who recognize that demonstrating their cleverness takes a backseat to being a professional. They can do that in their spare time.
If you have a question you’d like to hear my opinion on, please feel free to submit.
No Fields Found.
I’ve struggled with this concept over the years. I worked at an investment bank for many years, first as a developer, then eventually as a dev manager. I eventually ended up owning and maintaining much of the codebase that my team and I had written over the years, and I found myself cursing everyone on those teams (and myself) many times for writing unmaintainable code. I eventually formed the opinion that readability of code, over a long enough period of time, trumps almost every other factor, perhaps including correctness. My favorite example is the very first project I can onboard… Read more »
To be fair, your code was wildly successful. You solved a complex problem that was likely absurdly difficult given the original date of the software. It’s lived 10 years. It shouldn’t be surprising that it could be rewritten in a much simpler fashion with tools that are 10 years newer.
Personally, I sort of think of it like writing prose in a sense. If I felt, I dunno, poetic, I might write something with a lot of repartee, subtle jokes, or colorful turns of phrase — something clever. But if I’m giving someone directions or explaining how to use something, being clever is a detriment. I apply this heuristic to the software I write. Someone else’s dime, I’m giving directions. My own code, fun to be clever. Anyway, if you wrote something that’s been in prod, executing faithfully for a decade, it’s sort of hard to argue with. I mean,… Read more »
Generally, I agree that readable code is an admirable goal, but in the case you mention I think you highlight an exception to this rule. “Black box” components of “brilliant code” that no one can decipher but never break. In this scenario, you don’t need to understand the code. If it doesn’t fail don’t touch it and if/when it eventually does break, rewrite it from scratch
Agreed. I could probably have mentioned it more explicitly, but I have a general policy that, unless things are heavily under test, it’s best not to touch them until you have to. Then, when you have to, and you’re already incurring risk, you may as well improve them,
Good article. Thanks.
Of course, the real challenge is figuring out whether the code is “brilliant” because it’s overly complicated (and thus needs to be rewritten), “brilliant” because it’s in a more advanced but perfectly legitimate coding style (and so more junior developers need to learn and grow in their skills), or “brilliant” because the problem domain is inherently complex (and so trying to rewrite it would just move the complexity elsewhere).
I’m still trying to figure that one out. (And I suspect that the lines between #1 and #2 aren’t always well-defined.)
I think triangulating on which of the three it is goes a lot better when several members of a group/team are looking at the code. That’s been my experience, anyway, though, of course, this is still far from perfect.
The answer, I think, is that, “you don’t.” Some concepts are necessarily complex, and I am not in the business of giving my work away.
I’m not clear on what you mean by “giving your work away.” Are you saying that having hard to read code means job security?
Call it “dumbing down”, if you prefer, “training your replacements”, etc. That’s not in my best interest.