Improve your .NET code quality with NDepend
I first learned about cargo cult programming a few years ago. I remember thinking back then, “What a strange name for a programming-related concept.”
If you share my past self’s astonishment, then today’s post is for you!
First, you’ll see what cargo cult programming is and why you should care. Then, we’re going to look at some practical examples, using the C# language. Finally, we’ll close with advice about what you can do, as a developer, to avoid falling into this trap.
Cargo Cult Programming: Doing Stuff Just Because
According to Wikipedia, “Cargo cult programming is a style of computer programming characterized by the ritual inclusion of code or program structures that serve no real purpose.”
In other words, it’s when a developer writes code without really understanding it. The developer may use a very trial-and-error approach—maybe copy and paste some code from somewhere else and then tweak it and test it until works, or sort of works. Then the developer will stop tweaking the code, for fear it will stop working. In the process, maybe they leave some lines of code that don’t do anything.
Or maybe they tried to use an idiom they picked up from another developer while failing to understand that the contexts are different and it’s useless in the current situation.
Finally, it might just be lack of education: maybe the developer has a poor mental model of how the tools they’re using really work.
Why is Cargo Cult Programming a Problem?
As Eric Lippert puts it, cargo cult programmers struggle to make meaningful changes to a program and end up using a trial-and-error approach since they don’t understand the inner workings of the code they’re about to change.
This is not so different from what the Pragmatic Bookshelf calls “programming by coincidence” :
Fred doesn’t know why the code is failing because he didn’t know why it worked in the first place. It seemed to work, given the limited “testing” that Fred did, but that was just a coincidence.
That single sentence pretty much sums it up for me: if you don’t know how or why your code works, neither will you understand what happened when it no longer works.
Origin of the Term
Although practices that are considered cargo cult today have been recorded as early as the late 19th century , the term itself dates from 1945, when it was first used to describe practices that emerged during and after World War II between Melanesian islanders.
These islanders would mimic the soldiers’ behavior, such as dressing up as flight controllers and waving sticks, hoping that airplanes would descend from the skies with a lot of cargo.
Since then, the term cargo cult has been used in a variety of contexts to mean to imitate form without content—to perfectly copy the superficial elements while failing to understand the deeper meanings and workings of whatever one’s trying to emulate.
Talk is Cheap; Show Me the Code!
Enough with the history lesson. Time to see some code! I’m going to show you five examples of cargo cult programming in the C# language.
Checking a Non-Nullable Value Type for Null
This one is a pet peeve of mine since I see it a lot in production code. It goes like this:
public Product Find(int id)
if (id != null) // this check is useless
Console.WriteLine(“This line will always get reached.”);
return new Product();
Here we have a developer that probably doesn’t grok the difference between value and reference types . It would be completely forgivable, in the case of a junior developer, except for the fact that the compiler warns you about that.
You could argue that I’m nitpicking. After all, the code will run fine in spite of this. In fact, the check won’t even be included in the resulting IL, as you can see from this print of a decompiling tool:
There are plenty of worse problems, granted. Yes, the application won’t crash because of this. So what’s the big deal?
Well, for starters, I’d be worried about a development shop where the sole quality measure was “it runs without crashing.” But the real problem is that this type of code shows a lack of understanding of some fundamental characteristics of the language and platform that can bite you in the future.
Unnecessary Use of ToList() in LINQ to Object Queries
Like the previous one, this is something I routinely see in production code. Consider the code below:
var result = users.ToList()
.Where(x => x.PremiumUser)
.Select(x => new Name = x.Name, Birth = x.DateOfBirth )
The problem we have here is that these calls to ToList() are completely unnecessary (except maybe the last one, if you really needed the result to be a List and not only an IEnumerable).
In my experience, this happens when the developer doesn’t understand the nature of LINQ; they erroneously think that the LINQ methods belong to the concrete type List<T> instead of being extension methods that can be used with any IEnumerable<T> implementation.
By calling ToList() several times like this, the developer creates several new lists, which can be detrimental to the performance of the application.
You could rewrite the code above like this:
var result = users.Where(x => x.PremiumUser).Select(x => new Name = x.Name, Birth = x.DateOfBirth );
Consider the following line:
DateTime creationDate = DateTime.Parse(row[“creation_date”].ToString());
Here we have not only one but two unnecessary conversions. First, the developer creates a new string and then parses it to DateTime when a simple cast would have sufficed:
DateTime creationDate = (DateTime)row[“creation_date”];
This example assumes that the underlying database type is some specific type for dealing with dates (for instance, date or datetime in SQL Server). Of course, if you were using an inadequate type (such as varchar) then this would be a problem of its own.
Also known as Pokémon syndrome (“Gotta catch ’em all!”), the anti-pattern here is to add a try-catch block to every single line that could possibly throw an exception.
Bonus points if the code is attempting to catch System.Exception instead of a more specific exception, thus blurring the distinction between expected and unexpected errors.
More bonus points if the catch block doesn’t contain any code at all!
The general advice here is this: never catch unless you have a very specific reason for doing so. Otherwise, just the let the exception bubble up until it’s dealt with by the top-level exception handler.
If this advice seems vague (“How would I know if I have the right reason for catching an exception?”), that’s because it is vague. It’s beyond the scope of this post to go deeper into this matter, but Eric Lippert’s excellent article called “Vexing Exceptions” will greatly improve your understanding of exception handling.
It’s the stuff of superhero movies: after reading somewhere that concatenating strings by using the ‘+’ operator is incredibly inefficient, the well-meaning developer takes upon themselves the Herculean task of updating every single concatenation in the codebase to StringBuilder.
The reasoning for this is, of course, that
System.String is immutable. So every time you “modify” a string, you’re in fact creating a new instance in memory, which can hurt performance pretty badly.
Well, guess what? The compiler is pretty smart. Let’s say you have the following line:
string a = “Hello “ + “World”;
This, in fact, gets translated to
string a = “Hello World”;
The fast rule of thumb is it’s fine to use the simple concatenation when you know the number of strings to append in compile time. Otherwise, a StringBuilder probably makes more sense .
Of course, some scenarios aren’t that clear-cut. The only advice worth giving here is to do your homework. When in doubt, research and benchmark to your heart’s content.
I’ll leave you with more sound advice from Eric Lippert:
Unnecessary code changes are expensive and dangerous; don’t make performance-based changes unless you’ve identified a performance problem.
Is There a Remedy?
I’d say it’s fair to assume that more inexperienced developers are more prone to commit mistakes due to cargo cult programming. But no developer is really immune to it, independent of their knowledge or experience.
We’re only human after all. Tiredness, deadlines, cognitive biases, and (to be really honest) the eventual laziness can turn even the best developer into a cargo cult programmer.
Unfortunately, there’s no 100% guaranteed way of preventing this from happening. Yet there are some measures you could take to, at least, decrease the odds.
Let’s take a look at some of them.
Use Code Review/Pair Programming
The first measure you could take to avoid cargo cult programming is to simply get a second pair of eyes on your code. The benefits of having a second person reviewing each line of code before it goes to production can’t be overstated. And while code review and pair programming aren’t perfect equivalents, both of these practices will bring you this benefit.
Always Test Your Hypothesis
Write unit tests (and other types of tests as well). Monitor your application in production. If something doesn’t perform well, benchmark the heck out of it. Don’t just assume things. Testing your hypothesis can bring valuable insights and save you when your intuition gets it wrong.
Read Other People’s Code
Reading other people’s code is a great way to learn. It’s a perfect tool to compare your own ideas and assumptions against what other developers are doing, exposing you to novel concepts that can force you to gain a deeper understanding of the issues at hand.
In the era of GitHub , there isn’t much of an excuse for not doing that.
Learn From Your Tools
There are currently a plethora of tools that can help your team improve the quality of their code . Here’s the thing, though: you shouldn’t just use these tools. You should also learn from them. If you use NDepend, read about its rules . Try and understand the rationale behind them. What are the principles and best practices that guided its authors when coming up with the rules?
The same goes for other types of tools—and even the warnings the compiler gives you.
Computer Science, Not Computer Superstition
Even though no one is immune to cargo cult programming, we should strive to overcome it. There’s hard-earned industry wisdom at our disposal, slowly generated over more than seven decades. Let’s use it. Let’s understand our tools and our craft and write better software.
Carlos Schults is a .NET software developer with experience in both desktop and web development, and he’s now trying his hand at mobile. He has a passion for writing clean and concise code, and he’s interested in practices that help you improve app health, such as code review, automated testing, and continuous build. You can read more from Carlos at carlosschults.net .
Like what you just read?
Sign up to get all the latest news about NDepend, articles like the one you just read, and NDepend previews. Once in a while, you might get a special offer too. Unsubscribe at any time completely hassle free.
This just took me to my teen years around 13, where I was gluing up scripts in game called Ultima Online. There were really powerfull things you could do there and I would take some existing scripts that I got hold on to and combine them to do what I wanted. This was basically a trigger for me to become software engineer. So by my book, when you are starting and experimenting with code without any prior knowledge, there is no other better alternative than trial and error. You could learn it first, but then you would have no experience. With trial and error, you can get the drive for programming and it can change your view on coding from the very beginning.Reply
Hey Jacob, thanks for your comment! And I’m totally with you on this one: trial and error is often a great tool for learning. When stakes get higher though, it makes sense to put some extra effort into getting a deeper understanding.Reply
Thanks for this article. I agree with the importance of understanding what we are doing ! Idioms that we end up applying almost all the time should be even more understood, otherwise we won’t know what to do when we cannot use them, or when a better alternative exists.
Regarding StringBuilder performance, Jeff Atwood wrote a very interesting performance summary a few years ago : https://blog.codinghorror.com/the-sad-tragedy-of-micro-optimization-theater/Reply
Handling exceptions was a HUGE mystery to me in my early days. It deserves the special attention you gave it there because I see it a lot! I also see 0 exception handling from time to time…not even top-level…ugh!Reply
Leave a Reply Cancel reply
- Domain-Driven Design Demystified
- Should Architects Write Code? You Bet They Should!
- Hexagonal Architecture: What Is It and How Does It Work?
- When Is It Okay to Use a C# Partial Class?
- Extension Methods and the Decline of Traditional OOP
- November 2018
- October 2018
- September 2018
- August 2018
- July 2018
- June 2018
- May 2018
- April 2018
- March 2018
- February 2018
- January 2018
- December 2017
- November 2017
- October 2017
- September 2017
- August 2017
- July 2017
- June 2017
- May 2017
- April 2017
- March 2017
- February 2017
- January 2017
- December 2016
- November 2016
- October 2016
- September 2016
- August 2016
- July 2016
- June 2016
- May 2016
- April 2016
- March 2016
- February 2016
- January 2016
- December 2015
- November 2015
- October 2015
- September 2015
- August 2015
- July 2015
- June 2015
- .NET Core
- .NET Standard
- Bug Hunting
- Case Study
- Code Metrics
- Code Query
- Code Research
- Code Review
- Code Rules
- Dependency Graph
- Dependency Matrix
- Domain Driven Design
- IT Consulting
- Lets Build a Metric
- NDepend Features
- New Version
- Project Management
- software support
- Static Analysis
- Technical Debt
- third party
- User Voice
- Visual Studio
Cargo cult programming
Jump to navigation
Jump to search
Cargo cult programming is a style of computer programming characterized by the ritual inclusion of code or program structures that serve no real purpose. Cargo cult programming is typically symptomatic of a programmer not understanding either a bug they were attempting to solve or the apparent solution (compare shotgun debugging , deep magic ).  The term cargo cult programmer may apply when an unskilled or novice computer programmer (or one inexperienced with the problem at hand) copies some program code from one place to another with little or no understanding of how it works or whether it is required in its new position.
Cargo cult programming can also refer to the practice of applying a design pattern or coding style blindly without understanding the reasons behind that design principle. Examples are adding unnecessary comments to self-explanatory code, overzealous adherence to the conventions of a specific programming paradigm , or adding deletion code for objects that garbage collection would have collected automatically.
- 1 Origin
- 2 Cargo cult software engineering
- 3 See also
- 4 References
- 5 Further reading
Origin[ edit ]
Cargo cult on Tanna Island , Vanuatu
The term cargo cult , as an idiom , originally referred to aboriginal religions that grew up in the South Pacific after World War II. The practices of these groups centered on building elaborate mock-ups of airplanes and military landing strips in the hope of summoning the god-like airplanes that had brought marvelous cargo during the war.   Use of the term in computer programming probably derives from Richard Feynman ‘s characterization of certain practices as cargo cult science .  
Cargo cult software engineering[ edit ]
A related term in software engineering is cargo cult software engineering, coined by Steve McConnell . 
McConnell describes software development organizations that attempt to emulate more successful development houses, either by slavishly following a software development process without understanding the reasoning behind it, or by attempting to emulate a commitment-oriented development approach (in which software developers devote large amounts of time and energy toward seeing their projects succeed) by mandating the long hours and unpaid overtime, while in successful companies these might instead be consequences of high motivation instead of causes of success.
In both cases, McConnell contends that competence ultimately determines whether a project succeeds or fails, regardless of the development approach taken; furthermore, he claims that incompetent “impostor organizations” (which merely imitate the form of successful software development organizations) are in fact engaging in what he calls cargo cult software engineering. 
See also[ edit ]
- Copy and paste programming
- Cargo cult science
- Magical thinking
- Magic (programming)
- Voodoo programming
- Waving a dead chicken (over it)
References[ edit ]
- ^ Raymond, Eric S. (1996). “The New Hacker’s Dictionary”. MIT Press. ISBN 0-262-68092-0 .
- ^ Bezroukov, Nikolai. “Cargo Cult Programming article” . Softpanorama (slightly skeptical) Open Source Software Education Society. Retrieved March 25, 2008.
- ^ a b c “Cargo Cult Software Engineering” . IEEE Software . March–April 2000. Retrieved May 24, 2008.
- ^ “Definition of cargo cult programming” . Jargon File at jargon.net. Retrieved March 25, 2008.
- ^ McConnell (2003) , pp. 23–26.
- McConnell, Steve (2003). Professional Software Development . Addison-Wesley . ISBN 978-0-321-19367-4 .
Further reading[ edit ]
- Surely You’re Joking, Mr. Feynman!, Richard Feynman, W. W. Norton & Co, New York, 1985, ISBN 0-393-01921-7 . One of the chapters is the transcript of a 1974 Caltech commencement address, which contained the coining of ” Cargo cult science “.
- Cargo Cult Science, by Richard P. Feynman . Article based on his 1974 Caltech Commencement address, with pictures, as originally published in Engineering and Science, Volume 37:7, June 1974. Digitized version from Caltech Library, retrieved June 20, 2007
- Computer programming folklore
- Software engineering folklore
- This page was last edited on 8 March 2018, at 16:45 (UTC).
- Text is available under the Creative Commons Attribution-ShareAlike License ;
- About Wikipedia
- Contact Wikipedia
- Cookie statement
- Mobile view