“The best code is no code.” is something wise computer programmers will say from time to time. I think this is actually an alternate way to say “convention over configuration”, another frequently heard bit of philosophy in software development circles. Though some pragmatic reason is usually given (performance, simplified maintenance, lower cost, etc.) I think the underlying natural force behind these ideas is a desire for the conservation of language. The richer the vocabulary, the fewer words it takes to say something specific and the fewer verbose instructions are required. When you are limited to only a handful simple words, it can take a great deal of rambling to communicate an idea. It may even be impossible.
It is the glory of God to conceal a matter,
But the glory of kings is to search out a matter.
-Proverbs 25:2
What are the kings (or we) doing exactly? Figuring out how things work, yes, but immediately after that, or concurrently with that, they are naming things. They give things new names, they enrich the vocabulary. It now takes fewer words to describe a platypus because you can say “platypus” instead of, “That funny animal that looks like a cross between a beaver and a duck, you know what I mean?”.
So what exactly is God doing when he conceals things (his glory to do so)? He’s enchanting the world. He’s making it richer such that the words we have right now are NOT ENOUGH to describe it adequately. And we’re not stupid. We give it a shot and we immediately recognize that our vocabulary sucks. Not only that, but we can’t come up with a new name JUST YET. During the process of thinking of one, it become clear that we don’t really understand what we’re talking about. We don’t want to give it just any old name. It’s only satisfying if we give it a GOOD name. And so we must investigate what it is – tear it apart to discover how it works, or handle it for a long enough time.
People imagine Adam sitting casually on a rock and naming the animals in the garden by assigning new gibberish words to them, thus endowing the combination of syllables with meaning. But if Adam is anything like us at all, he would have thought about and investigated each animal for quite some time before deciding on a name. He might have even changed it around a bit as he went and gone back and made corrections as his observation broadened. It would have taken a long time. It would have been hard work to do a good job. He would have worked hard but he would have enjoyed it. It could have taken years. I wonder if he was done by the time the incident with the serpent happened? Maybe he thought he was done, but on that point he would have been very wrong. We, his grandchildren – billions of cousins we are – have only scratched the surface.
We think we’re so clever since we can now talk about the electromagnetic spectrum and Adam couldn’t but that wouldn’t have made his job any easier or his creative names any less impressive. The disconnect between the words and tools we have and the reality we are trying to describe is still just as vast. We try to talk about the distance between the stars using words like “red shift” and “dark matter” and “the expanding universe”. He tried to talk about the difference between two pine trees with novel words like “edges”, “points”, and “leaves”. Oh with what joy he would have leapt if the word “needle” and its full meaning were available for his task! It’s such a better word. What key word are we missing when we talk about deep space? Not sure… yet. It is concealed.
So programmers are always wrestling to say more with less code. If there is anything lacking in our newest crop of bright young developers it is a sense of history. They come up with some hip new Javascript framework and they think they are taking a leap forward in brevity when in actuality it is five steps forward and four steps back (or occasionally six steps back). They imagine themselves to be much more brilliant than their fathers, only to find themselves burdened with the same curse and similar limits, their new abstractions just as ‘leaky’ as the old ones. Simply swapping out a term here and there won’t make the architecture any better. It takes deeper thought and greater leaps to make the improvement we all desire.
Unit tests fix a real problem, but I’ve seen them make a project’s size triple. Now things are actually worse because your code is LESS maintainable, but you’ve deceived yourself into thinking it’s MORE so because of the tests. You pat yourself on the back for best practices and test coverage, even while your app breaks in the wild and the smallest feature changes now take 40 lines of work instead of 4. I think the best measure of whether some architectural element really is an improvement is brevity. At the end of the day, are you saying more with less? (Or at least the same with less?) Are you actually typing less crap in the long run? If the answer is “no”, then I suggest it’s time to go back to the drawing board.
One more example and I’ll be done – dependency injection, or “inversion of control” as it’s sometimes called. It’s a good idea and a useful way to run your software with simulated data for testing, or even an entire simulated environment. The problem is that with most implementations, it greatly increases the number of moving parts. A simple configuration approach might be 20 lines long, all in one file, and immediately readable and easy to adjust. I’ve seen dependency injections schemes span 20 files, invoke arcane syntax, introduce all kinds of mysterious reflection libraries, and even kill performance in some cases. “Oh but then your not doing it right!” the advocates yell. Well no kidding, but the people I know that DO do it right – many have them have eventually abandoned the practice, or at least scaled it back dramatically – only using it in certain cases. At the end of the day it was a lot more code, new jargon aside. But the best code is no code.
Take a deep breath and try again. You are Adam naming the animals.