The Trouble with Namespaces

By Guest

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:

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 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

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