While I sympathize with the avoidance of "clever" code, it's worth pointing out that there is an opposite direction: don't re-implement standard abstractions.
There are many standard abstractions that it is safe to assume that literally everyone qualified to touch code will know. If they don't, your priority should be either replacing them teaching them, not replacing the code.
Different languages and paradigms have different examples of such abstractions, but a trivial example is loops:
while(i < itt.length)
x = itt[i]
i = i + 1
for(i=0;i<itt.length;i++)
x = itt[i]
foreach(x in itt)
There is a decreasing amount of mental overhead in reading each one of those, because I know what a foreach loop does, and I don't need to be on the lookout for strange behavior.
IMO, Go overcorrects on the "don't get clever" ideology to the point of needlessly increasing the amount of mental overhead required to read some code. The entire language was designed to solve a problem that should have been solved at the hiring level.
> Resist the temptation to be creative, stylish, or (worst of all) clever.
I've spent a good chunk of my career coming in and cleaning up and optimizing codebases, avoiding complete re-writes . Coming across a genuinely clever and novel approach to a tricky problem that someone else wrote is something I enjoy immensely.
I'm tired of hearing from the "is unneeded complexity" bandwagoners. There is a difference between clever and convoluted. I'll trade a few more minutes of grokking for more performance, less boiler plate, etc, all day.
That and in my experience with large codebases, most time spent understanding code is spent on the business logic anyway.
I don't encounter overly clever code too often. But I do see excessive levels of abstraction all the time. Occasionally I'll see someone that doesn't use enough abstraction.
This is mostly what I encounter. An aim for simplicity with presumably the goal of clarity via abstraction that ends up with layers of layers of design pattern'ing that makes it damn near impossible to find where _something_ actually happens that isn't invoking another 3 line method.
Debugging is often a nightmare too, as you're trying to determine which abstract class is calling implementation of a given method, on top of a callstack 43 frames deep to accomplish nothing but code bloat.
It's my personal nemesis. I've finally just gotten to the point of memorizing "oh here's where the /real/ code is for this subsystem" after doing the interminable traceback enough times. Not a fan.
IME convoluted is often mistaken for clever. I've seen systems where the author was proud of how complicated their knots were but the reality was just a tangle to everyone else. Personally I guard for when I need to solve a problem but am having too much fun. It is usually a sign I'm too invested in the code than the goal, it helps me write but my next goal will be to edit it so future me won't say such awful things about now me.
Boring, repetitive code should be generated. Devs are a lot more expensive than compilers, and bored devs start seeing patterns that aren’t quite there.
There are many standard abstractions that it is safe to assume that literally everyone qualified to touch code will know. If they don't, your priority should be either replacing them teaching them, not replacing the code.
Different languages and paradigms have different examples of such abstractions, but a trivial example is loops:
There is a decreasing amount of mental overhead in reading each one of those, because I know what a foreach loop does, and I don't need to be on the lookout for strange behavior.IMO, Go overcorrects on the "don't get clever" ideology to the point of needlessly increasing the amount of mental overhead required to read some code. The entire language was designed to solve a problem that should have been solved at the hiring level.