I'm obsessed with organization - it's probably the real reason why I enjoy coding. So I namespace everything. But I'm just curious if I'm doing it wrong by being redundant.

Consider this, which I think is correct

namespace System {
   class File {};
   class Monitor {};
   class Logger {};

Now consider this, which is what I seem to be doing

namespace System {
   class SystemFile {};
   class SystemMonitor {};
   class SystemLogger {};

Am I being redundant? It's just that, SystemFile is a file in the system. SystemMonitor monitors the system.

In use cases, which would you prefer?

class Application {
      System::Monitor monitor;
      // or
      System::SystemMonitor monitor;
  • 1
    It all depends on whether you suspect users will be declaring using statements. If someone declares using System; then you don't need the System:: prefix for any class declared inside of it. – Berin Loritsch Jan 24 '20 at 19:13
  • @BerinLoritsch We never use using thankfully – errno_44 Jan 24 '20 at 19:14
  • And this is all internal code? Sounds like System::Monitor would be preferred in that case. – Berin Loritsch Jan 24 '20 at 19:36
  • @BerinLoritsch May be the other way round. If everything is called SystemThis, SystemThat then there is much more temptation to use "using System;". – gnasher729 Jan 24 '20 at 23:07
  • 3
    Does this answer your question? The problems with Avoiding Smurf Naming classes with namespaces – Theraot Jan 25 '20 at 1:41

Am I using namespaces wrong?

Wrongly. It's an adverb.

And the answer is probably.

In use cases, which would you prefer?

There are several reasonable tests. Is one easier to read, easier to say, easier to type, easier to fit in a readable expression or otherwise easier to use?

Can you take something out without impairing clarity, legibility, usability or correctness?

System::SystemMonitor monitor;

So, in my head this sounds like "system system monitor monitor".

Why not System::SystemMonitor systemMonitor? Or System::SystemMonitor::Monitor systemMonitor? Because they add more typing with no extra information and no benefit.

Conversely, if we start from System::SystemMonitor and simplify to get System::Monitor - can you see any downside? I can't, and if you can simplify something while keeping it clear and correct, you should generally do it IMO.

There are a couple of valid reasons to prefix types with the module name. One is that you're writing C, and the other is that you expect people to inject the whole namespace with using. You already ruled both of those out, so you have no excuses left for making your type names worse.

  • 1
    I agree. Now what about a case such as, Xml::File which extends System::File. Users within the Xml namespace will simply be able to create new File(), but will it be hard to understand that this is not a simple old File, rather it is an XmlFile? Because then you're back to Xml::XmlFile ... these are the things that keep me up at night. – errno_44 Jan 24 '20 at 20:46
  • 5
    I disagree. "Wrong and wrongly are both adverbs, meaning incorrectly, badly, or mistakenly.. Usage authorities differ on whether using wrong this way is acceptable, but in real-world usage, the adverbial wrong is not just widely accepted but common". "Am I using workspace wrong" is perfectly fine. – gnasher729 Jan 24 '20 at 22:19
  • 1
    @errno_44, as you already rule out injection of names with using, any name that you see without a namespace prefix must either come from the current namespace or the global namespace. I would expect a half-decent programmer to be able to easily remember or determine what namespace they are currently working in and the global namespace is likely to be nearly empty if you extensively use namespaces. That makes is rater easy to determine that new File() will create an Xml::File object if you are working within the Xml namespace. – Bart van Ingen Schenau Jan 25 '20 at 12:35
  • @gnasher729 - I'm not usually a prescriptivist, but I felt it helped to establish the right level of pedantry for this answer. – Useless Jan 28 '20 at 9:22

It depends of course of your intent.

If you intend to avoid naming conflicts and use primarily qualified names, the lean approach would be less redundant and easier to read: System::File is more convenient than System::SystemFile

If on the other side you prefer to inject full namespaces with using, then of course SystemFile would be less ambiguous. But what sense does it makes to create very specific namespaces in the first place, if it is for dissolving them in some kind of global magma afterwards.

Then, comes the question of consistency. Suppose that after a while, you decide to nest your System in a Platform namespace. With the lean approach you need not no worry: it’ll be Platform::System::File. With the redundant approach, you’ll need to decide if tou keep SystemFile, or if you go for Platform::System::PlatformSystemFile. So your names start to be coupled to the namespace organisation. This goes against the principle of separation of concerns.

Then come more advanced namespace strategies. Suppose that in reality you have a MacOS namespace and a a WindowsOS namespace, each implementing a slightly different File. At compile time you do some configuration, using namespace alias. For example:

 namespace System = Platform::MacOs;
 void doSomething() {
      using System::File;    // works regardless of alias choice
       File xxx; 

So, separation of concerns, i.e. keeping “item” names independent of the enclosing namespace offers you much more flexibility.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.