Are You a Cargo Cult Programmer?. Many programmers are, but you can learn… | by Guy Erez | Jun, 2022

Many programmers are, but you can learn to be different

Cargo Cult —

It goes back to WWII. As part of the war effort, the Allied forces had to build supply bases in strategic locations. Some of these locations were remote islands that had never come across the technological innovations of the 20th century. That means that airplanes, jeeps, and especially cargo boxes parachuting from airplanes all seemed like magic.

Naturally, the indigenous tribes living on those islands were ecstatic. Who doesn’t like magic and free food?

The problem started when WWII ended (not a phrase you hear every day).

The troops left, and food stopped raining from the sky. The tribe leaders must have then gathered to figure out how to bring the magic back. Their solution?

Recreate the scenery that accompanied the aforementioned magical occurrences. After all, there’s cause and effect in the world.

Sadly, that didn’t work. Apparently, building bamboo airplanes doesn’t make food rain from the sky.

The concept is summed up nicely in this terrific Feynman quote:

“In the South Seas, there is a cargo cult of people. During the war, they saw airplanes land with lots of good materials, and they wanted the same thing to happen now. So, they arranged to imitate things like runways, to put fires along the sides of the runways, to make a wooden hut for a man to sit in, with two wooden pieces on his head like headphones and bars of bamboo sticking out like antennas — he’s the controller — and they wait for the airplanes to land.

They were doing everything right. The form is perfect. It looks exactly the way it looked before. But it doesn’t work. No airplanes land. So, I call these things cargo cult science, because they follow all the apparent precepts and forms of scientific investigation, but they’re missing something essential, because the planes don’t land.” — Richard Feynman

So, we’re done with the history lesson. The only problem is — history tends to repeat itself. I sure as hell hope we’re not on the brink of WWIII, but Cargo Cults have spread far and wide, even into the realms of software engineering.

What is Cargo cult programming?

In a nutshell, it means doing things without really understanding why.
I’m sure you’ve stumbled upon such cases and even took part in them yourself. Let’s discuss some common examples.

The dreaded copy-paste

At some part in your career, you probably copy pasted someone else’s code. I know I did. I’m not going to discuss plagiarism, so let’s assume that code was meant to be shared freely.

And indeed, in a sense, every time you use a library, you “copy-paste” its code and use it as part of your code base. That could still lead to trouble, but that’s considered legit. Libraries are meant to be used by other people. The engineers who designed it worked hard on making it accessible and as bug-free as possible.

Problems arise when you copy-paste from some Stack Overflow answer, or from other parts in your code base — without having the slightest idea what that code is actually doing. It worked for that person, so why wouldn’t it work for you?

Well, that’s Cargo-Cult thinking. You’re dealing with the scenery (the code seems similar) without really understanding the root cause (how it’s used in that particular context).

Let’s say you manage to finish the task. The code works, you got the prize (cargo), but then circumstances change. A new request comes up, so you need to modify that code you didn’t really understand. And then it hits you — the airplane is made out of bamboo. Your code is not the real deal.

The first time you learn about inheritance, it seems magical.

With less than a line of code, you can get almost all of the parent class’s properties and functions. And don’t get me started on polymorphism, that is magical. The only thing they don’t teach you at school is that inheritance introduces very tight coupling.

Every time you inherit from a class, you create a very strong dependency on its concrete implementation. Even worse, every user of your class has a transitive dependency on the base class. That means that if someone changes the base class, which might even belong to a library you don’t have control over, your code may break. And that means every class that depends on your class may break as well, that’s no picnic, especially if it happens at the end of your work week.

Therefore, one needs to think carefully before introducing inheritance. You need to consider both the pros and the cons of inheritance, and figure out if your specific use case actually warrants it. More often than not, you should actually favor composition. In this context, I recommend reading this very interesting discussion, beginning with an answer from Uncle Bob himself.

The last example I’m going to give is a bit more specific. It’s related to copy-pasting code, but it’s much more elusive. It’s about using code/annotations you don’t fully understand, because it’s “best practice.”

A good example is the haphazard usage of the Transactional annotation in applications using Spring.

It magically seems to solve some bugs, so people think (and some probably even outright claim) it’s best practice to use it all the time.

The tricky thing about it is that 90% of the time, they’ll be right.
The bugs are solved, and the cargo keeps parachuting from the air.

Everybody’s happy until something changes and a production bug emerges in all its majesty. Look at the following sneaky example:

public void changeName(long id, String name) {
User user = userRepository.getById(id);
if (StringUtils.isNotEmpty(name)) {;
// All rights reserved to this fantastic article

An engineer with a keen eye can see that something here is fishy. Why set the name before validating?

However, a rushed code reviewer can miss this, and if they’re not familiar with the Transactional annotation, they might think no harm was done.

And then you start seeing records upon records of users with empty names. Crap, something must be wrong, is this a cyber attack?

Nope, it’s just our beloved Transactional annotation doing its job.

You see, there’s another overlooked side effect of this annotation — every entity declared in its scope is in a managed state. So every change you do in this scope is automatically persisted to the database, even without explicitly calling “save.”

In this case, it means you’re saving the records regardless of whether the validation succeeded or not.

  • Look under the hood. It takes time and can sometimes feel pointless, but down the road, it’ll help you save many weeks of battling bugs that defy reason.
  • Question “best practices.” Most of them are probably justified. But by questioning them, you get a chance to learn why they came about in the first place, which makes you a much better engineer.
  • Work on understanding things deeply. This may sound trivial, but we often settle for shallow knowledge. We confuse knowing something with knowing the name of something.

Some of this might seem like trivial common knowledge. But remember, common knowledge isn’t always common practice.

Be mindful of your work, and spend more time learning the intricacies of your craft. You’ll be glad you did.

News Credit

%d bloggers like this: