The Trouble with Namespaces

By John S.

Today, I’m going to talk about the way my attitude towards using namespaces has pretty much done a complete reversal over the last couple of years.  I started off thinking that they looked great, progressed to mild concern that they seemed to be causing unexpected difficulties, and eventually realized that they can become unmanageable if allowed to grow out of control.  Just like a bunch of tribbles. (Yes, the title is a Star Trek reference :).

  To jump to the punch-line, I’ve come to the conclusion that highly fragmented hierarchies of namespaces (such as are found in .Net and encouraged by the Visual Studio C# IDE) make life harder rather than easier.  Instead, I would recommend either name mangling strategies (incorporating an identifying string in the object name) or always using fully qualified names in your code (instead of “using” statements).

Phase I: Infatuation

  When namespaces were first introduced into C++, I thought they looked like a great idea.  It seemed wonderful to not have to worry about managing name collisions.  Unfortunately, for over a decade I didn’t have an opportunity to use them; my Physics codes were standalone executables (and so name conflicts weren’t an issue), and ACIS was written before they were portable to all compilers.  Actually, ACIS was written before they were introduced into C++.  In the tribble analogy, everyone else got to play with these cool critters but I didn’t have one.

Phase II: Nagging Doubts

This changed when I started working with C#, especially in my personal projects at home.  The .Net library makes extensive use of namespaces to indicate areas of functionality, plus the Visual Studio IDE assumes you want this sort of hierarchy in your code.  If you create a folder within your solution to manage an area of functionality, for example a Market component in an economics simulator with root namespace Econ, then the Visual Studio class wizard “helpfully” puts any classes you add to that folder into the “Econ.Market” (sub-)namespace.  And that is where the trouble started.  (If anyone knows how to turn this behavior off, please post a reply – I’ve been unable to find a way to do it.)

I quickly found myself getting frustrated by not having the correct set of “using” statements in my code, and having difficulty figuring out which “using” statements I needed to include.  For example, if I had a Trader class in a Actors folder (and corresponding namespace) and a Pit class in the Market folder, then I would regularly get compile errors when I tried to use the Trader class without “using” statement for the Econ.Actor namespace.  And the really frustrating part was that it wasn’t immediately obvious which namespace was missing – I would have to find the class then look to see which namespace it was in.  I now realize that the problem that I was running into is that namespaces (or more precisely “using” statements) lead you to write non-self-documenting code.  In other words, if I write the code

Market market = new Market(); 
GoodsType goodsType = new GoodsType(); 
Pit pit = market.GetPit(goodsType);

I don’t have any visual indication in that region of code as to which namespace Pit, Market, or GoodsType live in.  And if they come from several namespaces, I don’t know which “using” statement corresponds to which class.

This is very similar to the C++ “which header file declares this class” problem, for which a really good solution is to simply make the header name identical to the class name.  CGM uses this naming convention and I highly recommend it – you don’t have to think when writing your include statements.

Phase III: Regret

The final driver on my voyage of discovery was C3D development (in C++).  When we first started writing strong commands, I had the bright idea to use a namespace hierarchy to put a structure on the vast sea of commands we would be writing.  Unfortunately, it didn’t work out as planned.  Even though we only introduced a few namespaces, they still made life much more difficult than a simple name mangling scheme would have.  Part of the problem is that the compiler errors when you get the namespace wrong are not helpful:  we had to train ourselves to ask “did we get the namespace right” when we see an “undefined symbol” error for a class that we’re sure has the header included.  An especially nasty error occurs when you try to include a header file inside a namespace block (this typically happens if you’re using templates and so want to do another round of includes for the method definitions).  If I had it to do over again, I’d settle for a simple “_SPA” or “_CGM” at the end of each class name, e.g. Property_SPA rather than Spatial::Commands::Property.  In tribble language, I feel like Kirk standing awash in a sea of tribbles.

Phase IV:  Lessons Learned

The first thing to make clear is that I am NOT saying that namespaces are bad.  The fundamental problem that namespaces solve is the ability for application writers to manage naming clashes between libraries from different vendors.  I think it’s a great idea for every company selling component software to put everything into a single company namespace.

The problems I see come from trying to group classes into complex hierarchies, especially if you then use “using” statements to erase knowledge of the hierarchies.  I’ve come to the conclusion that any such grouping should be as simple as possible, and that the primary goal of the grouping should be avoiding name clashes rather than imposing a component structure on the classes.  The reason for this is that classes move between components fairly easily, especially if the component structure is very fine-grain.  If every time a class moves you have to do a major renaming effort (either to fix using statements or to rename the class) then you’ll generate a lot of worthless work for yourself.

With this in mind, I currently think a name mangling scheme, with the disambiguating string at the end is best, i.e. something like ClassName_NS.  The reason for putting it at the end rather than at the beginning is to help search – if you’re looking for class “Beagle” but are not sure which namespace you’re in, then you just need to look for “Bea*” in a list of all class names.

All of the above being said, I shudder to think about trying to solve this problem in a huge organization.  Would .Net really be easier to use if they had used the above naming scheme rather than relying on namespaces?

Tags:

Cool! (on "namespace detail"

Cool! (on "namespace detail" matching my suspicion). I assumed when I wrote the post that there would probably be a lot of people for whom it wasn't news - it sounds like the Boost gang falls into that category.

John

Well, my particular library

Well, my particular library is open source, no it's ALL open for the world to see =)

I think my Boost comment was misleading - by 'various detail namespaces' I meant that they use 'namespace detail {...}' in lots of places inside 'namespace boost {...}', not that there are several differently-named detail namespaces. So they are in fact doing exactly what you suggest (although some of the Boost sub-libraries have their own namespaces, which I do actually find annoying more often than not). It is interesting to look at the Boost sources occasionally - from a comment on Stack Overflow, "It's where the wizards hang out and they deal in template magic", so it's often hard to read, but there are lots of neat tricks and techniques in there.

Totally agree with 'no using statements in included files', I follow that pretty religiously myself.

Hi Ian, Ahhhhh templates,

Hi Ian,

Ahhhhh templates, where your entire implementation is included in the header for all the world to see :)

I agree that if you're providing a library with a templated interface then namespaces are a good way to hide implementation items that you don't want to be visible. But my central thesis is really "Avoid using using statements", and this usage is consistent with it. One should generally have a coding standard "no using statements in included files", so that means that you should be using fully qualified names like Solver::Property in such templated code. The other part "avoid incorporating highly fragmented component naming schemes in your classes" still holds here; I suspect life would be easier for the Boost folks if they used a single "Boost::Implementation" namespace for all those hidden bits. (Disclaimer: I've never used Boost.)

On vector.length(), we still agree :)

Thanks for the interesting discussion,
John

Hi John, I think we agree

Hi John,

I think we agree with each other on point 2 =) As for the 'detail' namespace, I agree that it isn't needed when you can just hide stuff inside source files (and not export it). However, when C++ templates are involved the situation is different. For instance, the Boost libraries use 'detail' namespaces extensively to hide auxiliary/helper classes and functions that shouldn't be used directly by the end user, and I've used that technique myself occasionally for my own template code.

One more note on Effective C++ Item 23: the principle applies to non-static member functions too. For example, I much prefer a vector/matrix library that uses the syntax vector.length() instead of length(vector), for all the reasons mentioned earlier.

-Ian

Hi Ian, Thanks for your

Hi Ian,

Thanks for your response! I found three separate issues you bring up; please let me know if I missed any :)

1) Nested/Internal namespaces: I haven't ever tried to do this (use namespaces internal to a component that aren't exposed to clients), but my gut tells me that it isn't likely to be needed in practice. The reason is that namespaces' primary role is disambiguation, which should not be necessary for the "private" (non-exported) objects within a component. If the internals of a component are so large as to need further categorization, then you probably want to break the component up into sub-components. If not, then you're back in the situation I mentioned where you either need to change a lot of code when an object moves between sub-components(' namespaces) or have every file in the component have a "using" statement for ALL of the sub-components' namespaces. In the latter case, why bother having namespaces if you're not going to use them in your CPP files?

2) "Property_SPA" vs. "Spatial::Property": For the company namespace, I'm fine with Spatial::Property. This is where the value of namespaces comes in - I don't have to tack an extra (hopefully) disambiguating string in my class names for fear of clashing with another vendor. The first thing I'm advocating is to try to minimize any further levels of detail, i.e. prefer (Spatial::)Property over either (Spatial::)Property_Solver or (Spatial::)Solver::Property. If that fails, then I prefer Property_Solver over Solver::Property exactly because it eliminates the possibility of using statements; this means that the code is forced to be self-documenting. In addition, if you're doing this because "Property" clashes within your code base, then searching for "Property_Solver" will give you only relevant hits, while searching for "Property" might give you hits on Object::Property, with no way to distinguish between the two if someone put a using statement in the file. If you forbid using statements, then Solver::Property vs. Solver_Property vs. Property_Solver all have the same information content, and at that point the ease-of-search argument wins. And thanks for reminding me about auto-complete - that is an even stronger argument (that I forgot to make) in favor putting mangling information at the end of the name.

3) Item 23: I agree completely. I think that using a class object as a namespace for its associated elements (as static members) is a much better practice. In fact, just last week I moved a couple of free-floating functions into static methods of a class. This practice works VERY well in C#; we've found it very useful to even include private helper classes inside other classes.

Using your example, I agree

Using your example, I agree that nested namespaces like Spatial::Commands::Property are probably not a great idea, but is there a reason you prefer Property_SPA to Spatial::Property?

I personally like the pattern of each vendor having their own namespace, possibly with a nested 'detail' or 'internal' namespace for code that has to be in headers but that clients shouldn't have to worry about. I do think it's useful to be able to use 'using namespace ...' in local, targeted ways (like in one self-contained source file or even within one function body) and the suffix method eliminates that possibility.

I do like your point about the suffix method leading to easier-to-search-for classes - I don't think people pay enough attention to making code documentation-friendly. One of the few points in Effective C++ I disagree with is Item 23, 'Prefer non-member non-friend functions to member functions', which argues that anything that *could* be implemented as a free function instead of a member function of a class should be. I think that makes it harder to discover what can be done with objects of a particular class, since you can no longer just go to the documentation page for that class (unless the library developer has been very careful with cross-linking), nor can you type 'someObject.' and use autocomplete.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.

More information about formatting options

Twitter Facebook LinkedIn YouTube RSS