Mitigating Code Complexity for Hard Problems


Lately I’ve been thinking about my current general philosophy on how to approach the code I work on each day…

When I’ve solved a hard problem (or have a design for a solution in mind), I ask myself the following questions:

1) Would a slightly more junior developer understand the code I just wrote? 
          …See the genius behind the design I just implemented? 
               …Understand why I wrote it the way I did?
2) If (or rather when) there is a bug with the code, would a slightly more junior developer understand how to debug this code?

If I can’t easily say “yes” to the above questions, the code is either too clever or over-engineered.

To me, being too clever and over-engineering are two completely different problems that have their roots in the same core issue of complexity.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” 
          –Brian Kernighan

If I’ve lost you here, let me insert a little example and explain -

# Perl.pl excerpt
#
#

my @matches = grep {$$hash{$_} ~~ /($target)/} keys %$hash;

# my @matches;
#
# foreach my $key (keys %$hash) {
# my $value = $$hash{$key};
# if ($value =~ /($target)/) {
# unshift @matches, $key;
# }

So we have a single line of code that replaces a bigger loop with fewer lines of code. It’s genius!! And I’m sure there is no way there will EVER be any reason for any future developer to have to look at or change this line of code. (…history says otherwise)

But when someone does have to look at this line in the future, a more junior developer might not understand what it actually does (it is rather complex after all). If there is ever a bug with that line of code, it’s not easy for a novice to just set a break point and see what its doing, especially when the problem likely involves the data being different than the original developer anticipated.

So what to do?

Well, the first question is: how much better IS this line of code?

If it’s simply shorter than the alternative, it might be a good idea to go with the ugly loop for readability purposes. However, if this one line of code executes much faster than the loop, it’s a tougher question.

Performance isn’t always better…
If this line only ever executes once, you still might want to re-write it back to the loop anyway. Sure, it might cost the user an extra few milliseconds every time they visit the app, but that’s a small price to pay for code maintainability.

On the other hand, if this line of code is executed a LOT, then you might really need to go with performance over readability. In this case, the best you can do is document what this line does.

To me, documentation is the LAST ditch effort to building good maintainable code. It’s something you do after you fail to make your code simple and/or self documenting.

In a few days I’ll take this further, and discuss how to properly comment the above code.


Edward Romano Written by:

I dabble in, and occasionally obsess over, technology and problems that bug me