hello.

this is a programming blog

On Namespaces

This work is about C++ namespaces.

This is not about C#, Java, nor any other language designed with alternative brevity.

TL;DR

Introduction

I didn’t think I had to write this post.

I thought everyone had naturally learnt, through frustration and agony, what to avoid when using namespaces. I thought all the C-with-classes folks had died, adapted, or ensconsed themselves in a fortress of code that was too important for their organisation to lance.

It turns out I’m super-wrong; namespaces are getting misused all the time. I watch in horror as someone tours me through their codebase and whispers, with pride in their eyes and idiocy on their tongue, “here is our teams namespace”. Heavens friend, I’ll stab you with my Learning Knife.

Namespaces For The People Code

A codebase is made up of code like algorithms, data-structures, routines, and global variables because you’re a monster. Namespaces are a tool to organise that code into cognitively separate chunks, so that us idiot humans can more easily store the whole thing in our head. Good code organisation leads to an easier time navigating a codebase, inferring where pieces may lie like a well-drawn map.

A codebase is not made up of people, teams, JIRAs, initiatives, or whatever bastardization of Agile Development you’ve half-remembered from a fever dream. People aren’t present in code; a team isn’t present in code; if you see namespaces that designate which people code belongs to you are seeing an anti-pattern.

Don’t use namespaces to designate your company, organisation, or team. Use namespaces to separate libraries, systems, and code into cognitively distinct areas within your codebase.

Physical evidence of me quitting a job

I shall now rant about top-level company namespaces.

An all-encompassing namespace that bears the name of an organization is the most common mistake I see with “people namespaces”. If this top-level namespace is the only one of its kind then I suspect narcissism as much as a lack of understanding, and you should delete it.

A top-level company namespace only does one functional thing - it prevents any nested namespace from clashing with an external library. In all my years I can not recall any top-level namespace clashing with another, and it is straightforward to work around clashing namespaces.

The downside is that it’s a pain to type every time. How do engineers get around that? They put everything inside the organisation namespace, so it’s like it doesn’t exist in the first place. Wow what smart people, they effectively deleted your namespace for you. Save them the trouble and don’t include it from the start.

“But what about all those little utility functions and things, they can’t just live in the global namespace like a tramp in the woods”. Firstly, weird analogy dude. Secondly, this pattern of thinking is wrong. You should see a collection of useful functions and think “I should wrap these in a library with a nice short name”, like std except not that because it’s already taken.

I realise that there may be teams that share the same name as the piece of technology they’re working on - for which there might be a corresponding namespace. I hope you’re smart enough to realise that I’m not talking about you. If the namespace makes sense for the code, I don’t care if your team is similarly named. Call your team Global Namespace for all I care. I’m offended you made me write this caveat out.

Go Wide, Not Deep

Suicide Is Painless

In life if you wish to promote a particular behaviour I recommend removing barriers that makes that difficult. The two primary barriers to engineers engaging with your namespaces are keystrokes-per-second, and thinking-units-per-interaction. Deeply nested namespaces fall afoul of both these.

Engineers will hate a codebase if they have to type a lot of characters to access every function or type within it. They will stop being good citizens and go rogue, they will start writing using namespace, and they will call you names. You will have failed with your design because it is hard to use.

Remembering where particular functionality lies becomes harder in a codebase with deeply-nested namespaces. I speculate due to the lossy nature of human memory that this falloff is super-linear. In every case it is worse. If you have usable functionality in a three-levels-deep namespace, you are probably in a sad place.

The solution, friends, is to nest less.

If your codebase is large with nicely named distinct bits there is the temptation to carroul these pieces into groups; engineers are frightened of numbers greater than six. Muster your courage and allow fifteen, twenty adjacent namespaces. Realise that the number of namespaces has not changed. Instead the amount of overhead to engage with them is reduced. Engineers do not have to remember to which namespaces the namespaces belong.

Yeah I’m not including internal or detail namespaces. Those are an artefact of the language, and not the topic today.

A Rose By Any Other Namespace

(This bit is more subjective than the obviously factual sections above)

Names are hard. I get that. That’s why salespeople are employed to think up the perfect intersection between a word that is catchy and a word that represents a product. You have to be that salesperson for your own code. Codebases quickly grow too large for people to know the contents of every line. In a large enough codebase you must sell the functionality of the code within. We must sell to ourselves, because future us don’t remember. The engineer I curse with the most frequency is me of coding-past.

The name of a product is outside the scope of this rant essay. I don’t have rules for what constitutes a good name for a product. I do have rules for what makes up a good namespace. You may notice the concepts of keystrokes-per-second, and thinking-units-per-interaction rear their heads again. At the end of this list you will know why I consider std to be a good namespace.

Using Namespace

You should never place a using namespace statement in any scope greater than a function-body. It’s well-known that placing said statement in a header-file is obviously bad, as you pollute all translation units which include that header-file. Given engineers propensity to include random header files at the drop of a hat and you will soon have polluted your whole codebase. These days, with the proliferation of unity builds, the translation-unit scope is no longer safe. That means you can’t put a using namespace at the top of your .cpp file as a unity build will pollute all adjacent source files. So… don’t do that.

Conclusion

You’re all terrible people.