10 Unpopular Assertions About Programming

·

11 min read

Sprint Demos are boring and weird.

The vast majority of development work involves working on utilitarian code like API implementations, UI fixes, and business logic. As satisfying as it may be to work on, it's never going to be a spectator sport. The number of hours I've spent listening to people who, let's face it will never have a career in show business, dryly talking a room full of people through the intricacies of an API change they've implemented, is truly depressing. Congratulations on spending the last two weeks doing your job, but do we really need you to put on a show? Just write it down and let us peruse it, if we are interested.

No other jobs do this. Imagine a bunch of builders constructing a house. Every two weeks they don't feel the need to demonstrate what they've been doing to each other - we know what you've been doing: your job.

"Hey guys, thanks for coming along to our demo of what we've been doing in sprint 378. We'll start with Mick the Sparks who's going to show some exciting work he's been doing with the electrics. Over to you Mick."

"Thanks. I've been working on putting these snake-like things we call cables throughout the house so that electricity can be carried from the pole outside to every room in the house. We can then use that electricity to power various types of consumer goods. I've prepared a demo for you: when I flick this switch here you should see it working."

Flicks switch. Light comes on. Golf clap. Awesome Mick, awesome work.

But of course 50% of the time the light won't work because demonstrations are cursed. Let's not do this anymore.

End users should never see 500 errors unless shit is actually on fire.

HTTP has a plethora of well-designed error codes that were designed to convey to an end user, be that a person, or program acting on behalf of a person, that something is wrong. Out of all the codes, the most useless from the point of view of the caller is the generic 500 error, which means "something went wrong on the server." There is literally no action the client can take when confronted by this error, beyond trying again and hoping it works the next time. Retrying in the face of such a failure may also end up exacerbating the problem by causing a denial of service attack, as clients repeatedly retry and fail. Other errors in the 5XX range can actually convey useful information and even imply courses of action for the client, but 500 itself is utterly useless.

There is only one reason why a server should send out a 500, and that is if the situation is completely unknown such as the data center being on fire. Even then, the people who really need to know are the server-side teams rather than the clients, so returning it isn't going to help; but fair enough, you have to return something.

The following scenarios are absolutely not suitable for a 500 response:

  • The user sent invalid data.

  • The user is attempting to hack the server.

  • The database is offline.

  • The developer didn't handle the request the client's making.

  • The developer couldn't be arsed to find a more informative error code.

If you're implementing an API, you may as well respond with a 418 ("I am a teapot") rather than a 500, for all the use it is. At least it'll give the end user something to think about.

The more "features" your language has, the more likelihood that the resulting code will be unmaintainable.

A hundred years ago, there was a ubiquitous programming language called "Perl" that had the motto "TMTOWTDI", which stood for "There's More Than One Way To Do It"; Perl's proponents were very vocal about the efficacy of this facet of the language. Meanwhile, Python had the notion of code being "Pythonic", implying there was a right way to do things, even though you could achieve your goals in multiple ways, which is pretty much in direct opposition to the Perl mindset.

By the way, the fact that Python is still here running things in 2023 and Perl is essentially moribund is not related to this issue. Probably.

Over time it seems like people tend to fall into one camp or the other but for me, and in the context of developing as part of a team, the choice is clear: if there is a generally accepted best way to do something, why wouldn't you use it? OK, it can feel restrictive, and not as "expressive", but really, why do people feel the need to be "expressive" in code? If you need an outlet, why not learn the piano, or go to dance classes or something?

One of the things that attracted me to Go was that part of the design involved removing unnecessary language features in favor of having well-thought-out primitives that were flexible and functional. For example, unlike most other languages that have multiple ways to perform a loop (do...while, while...do, for, foreach, etc), Go has just one, and it is flexible enough to use for pretty much any scenario.

Compare this with Rust's five (FIVE) loop constructs. Why? Why do you need to decide which one of the five loop types to use? How does that make the code easier to write or read? Is this you wanting to express the pain in your soul again?

Some languages, including Rust, suffer from severe feature bloat. Developers come from a wide variety of backgrounds and have vastly different experiences; you can't please them all, but it's like the language creators seem to want to try. Every year languages get new features added, new paradigms invented, and new syntax extensions until they all become vast, ugly, Frankenstein's monsters that try to be all things to all people. In turn, developers will use features they like and you end up with unmaintainable code, as every file becomes stuffed with different idioms. At this point, some frustrated programmer will decide to create a new language that is less obnoxious, and the cycle starts all over again.

It is impossible to make an accurate progress indicator.

There are some things that computers can't do. These include the halting problem and progress indicators. Don't waste your time trying to make an accurate progress indicator. Believe me, I learned this the hard way after spending several developer-months watching people try and fail to please the product owners.

If Apple and Microsoft can't do it after 30 years, you're not going to manage it. Someone needs to come up with a mathematical proof.

The whole notion of "clean code" is bullshit.

A long while ago, a man gained popularity for being opinionated about how to write code - can you imagine such a thing? He wrote a book called "clean code" which was very popular amongst a new generation of young brogrammers who liked his attitude and advice. To cut a long story short, both he and the book are quite flawed, but both still have legions of quasi-religious followers.

In the case of the book, there is a bunch of really obvious suggestions, a handful of really good suggestions, and a few bloody awful ideas. The main problem is the entire notion of "clean code"; it's a completely meaningless statement that invites people to interpret it in any way they wish. To "Uncle Bob" (the author) it basically means any code that he personally likes. To his fanbois, it means anything they bloody well like, and that they can justify by saying "this is cleaner". They may as well say "this is saltier" for all the sense it makes.

As mentioned above, the book contains some very bad advice, but the one that really irritates me is his advice on commenting code: he considers comments to be a sign of failure. In his mind, if you have to comment the code, you haven't written it clearly (cleanly?) enough.

There are two simple rebuttals to this:

  1. Comments should explain the intention of the code. The code shows you what it actually does. If the two don't match you need to do some investigations. If there's no comment, all you can do is assume it's correct and treat it like a cargo cult, or assume it's wrong and do it your way (despite the fact it's probably been working ok thus far).

  2. JUST FUCKING COMMENT YOUR CODE! If you've ever had to work on a massive codebase that isn't commented, it doesn't matter how "clean" it is (it never is), you want to strangle your forebears. Write comments.

The less code, the better.

In his excellent book, The Philosophy of Software Design, John Ousterhout gives us the benefit of his vast experience. This differs from the advice of Uncle Bob (see above) in a number of ways, but there are things they, and any experienced developer, will agree on. A significant concept that seems to be universally acknowledged is that the enemy of effective, maintainable code is complexity. Complexity, in this sense, encompasses a large number of concepts, but one dead giveaway of a complex codebase is its size.

Despite this, there are a considerable number of people in the industry who regard the number of lines of code committed as a positive indication of productivity or, worse, quality.

Once a codebase is in production, it's usually better for maintenance PRs to have a negative line count. Yeah, I said it. And obviously, this doesn't apply to changesets that are implementing new features.

Another concept that John Ousterhout discusses is that of "tactical tornados" - the ones who go away from the planning meeting and generate thousands of lines of code to get the job done. They are a menace.

Well-known design patterns aren't necessarily a good idea.

Can you believe that there was ever a time before that bloody book came out? Before that no-one had any method to implement common algorithms and so computers didn't do anything useful. Oh wait... they worked fine and people worked just as well (if not better) than now. So why is the notion of a "software pattern" so revered? Perhaps it's like the Pythonic notion: there is a best practice way of doing things. Well great, but good Python idioms existed before the term was coined. So what are these patterns? Useful algorithms perhaps? No, we already had a name for them: "useful algorithms."

Worse, some of the patterns are bizarre and promote terrible habits. For example, The Singleton. When I first heard about this I didn't understand what it meant:

"It's code that should only ever be run once."

"OK then, but why would you run it more than once in the first place?"

"Well, you don't know, something else could accidentally run it again"

"Like a bug you mean?"

"Yeah, or anything. Another thread or something."

"Can I not work with you anymore?"

There will be people who don't know what I'm on about here - make sure your team never hires me, and if I turn up for an interview tell the boss I won't be a good culture-fit or something.

Rewriting from scratch is almost certainly the wrong answer.

Joel Spolskey described rewriting the codebase from scratch as the "single worst strategic mistake that any software company can make." He explained it better than I ever could, so read his words of wisdom.

If you end up re-architecting code during a code review, your development process is broken.

Code reviews, when executed well, are fabulous tools for identifying potential problems before they come back to bite you. But they can also be opportunities for egotists, bullies, and general gobshites to make themselves feel superior.

Over the years I've observed so many unpleasant situations where people with a strong personality effectively bully those with less confidence into rewriting their code. It wouldn't be so bad if others stepped in and disagreed, but that is bafflingly rare.

When code reviews become battlegrounds, the wrong people often win.

If nobody spotted a problem with the "story" (as agilistas call tasks) then the worst time to address it is when some poor sod has spent a week implementing it.

Spot design problems early on - and yes - that does mean discussing stuff in person before too much work is done on it. If you bring this up in a code review then you are at fault for not spotting it sooner. Alternatively, you may just be an awful person.

Routine praise and shout-outs can massively backfire.

This is a tough one to argue because the whole notion of publicly praising someone for doing good work is an objectively nice idea. Positive reinforcement is a solid and reliable technique for getting the best out of people, so how could anyone be against it?

It's simply that when it becomes routine, it goes from making certain individuals feel happy, to making other individuals feel useless; frequently the division goes along lines between the strong and weaker personalities, or between the extroverts and introverts.

When your weekly list of praises regularly gets into multiple pages, you need to start looking out for the people whose names never come up. Should they be fired? Or are they just diligently doing their job quietly?

We're back again to the sprint demo problem: calling out people for doing their job helps no one. To the person called out, it can become an expectation (especially if they have that type of personality) - to the people who are always overlooked, it just becomes a burden.

Thanks for reading. Sorry if you hate me as a result.
Regardless, share and enjoy.