Comment by userbinator
2 days ago
Looking at all he has done, I don't think he means "complex" when he says "clever". He's not advocating for (and most likely against) the architecture-astronautism of overengineering that some people seem to be associating with "clever" here.
He means code that appears indecipherable at first glance, but then once you see how it works, you're enlightened. Simple and efficient code can be "clever".
I think clever is being used in two different ways, in that case.
In the original quote, “clever” refers to the syntax, where they way the code was constructed makes it difficult to decipher.
I believe your interpretation (and perhaps the post’s, as well) is about the design. Often to make a very simple, elegant design (what pieces exist and how they interact) you need to think really hard and creatively, aka be clever.
Programming as a discipline has a problem with using vague terms. “Clean” code, “clever” code, “complex” code; what are we trying to convey when we talk about these things?
I came up with a term I like: Mean Time to Comprehension, or MTC. MTC is the average amount of time it takes for a programmer familiar with the given language, syntax, libraries, tooling, and structure to understand a particular block of code. I find that thinking about code in those terms is much more useful than thinking about it in terms of something like “clever”.
(For anyone interested, I wrote a book that explores the rules for writing code that is meant to reduce MTC: The Elements of Code https://elementsofcode.io)
Good code should not be immediately understandable. Machines that do pasta do not look like humans that do pasta. Same for code; good code does things in a machine way and it won't look natural.
Example: convert RGB to HSV. If you look around for a formula, you'll likely find one that starts so:
Looks very natural to a human. Thing is, as we compute 'cmin', we'll also compute or almost compute 'cmax', so if we rewrite this for a machine, we should merge these two into something that will be way less clear on the first glance. Yet it will be better and make fewer actions (the rest of the conversion is even more interesting, but won't fit into a comment).
Recognizing that sort of opportunity is why we have optimizing compilers and intrinsics.
Funny thing: in Python code I've had a few occasions where I needed both quotient and remainder of an integer division, so naturally I used `divmod` which under the hood can exploit the exact sort of overlap you describe. I get the impression that relatively few Python programmers are familiar with `divmod` despite it being a builtin. But also it really doesn't end up mattering anyway once you have to slog through all the object-indirection and bytecode-interpretation overhead. (It seems that it's actually slower given the overhead of looking up and calling a function. But I actually feel like invoking `divmod` is more intention-revealing.)
In short your stance is to sacrifice readability for performance.
Legit in some cases. But for usual business software, code is for humans (compiler will make machine code intended for the machine)
Readability belongs to documentation. Code should have certain technical aesthetic, it should be easy to navigate it, but why its operation should be obvious more than that of any complex mechanism? Nobody demands a mechanical watch to be readable or have meaningful names for the parts.
It is not just performance. A minimal component gives you flexibility: you may make the whole system performant or you may trade extra performance to reach a different goal, such as robustness or composability. It is a more fundamental principle, common to construction in general: a thing should do all it has to do and should not do anything more.
2 replies →