473,395 Members | 2,253 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Why namespaces?

I work in a small company with developers who do not like to use "new"
features when they find the old ones sufficient. e.g. given a choice
between a class and a namespace, they'll pick class. Given a choice
between naming functions at the global scope with subsystem prefixes
(e.g. CTNode, CPNode) vs. namespaces (Time::Node, Place::Node) we'll
use the global namespace. Prefixes they understand, and prefixes are
short and do the job. Namespaces require more typing.

We understand why namespaces are good for library developers: we can
avoid name clashes. But the benefits for our own development are less
clear to me.

So here's my question:

Is there any advantage to using namespaces vs. using subsystem
prefixes? And specifically, can the compiler and linker run faster
with namespaces?

Stuart

Jul 23 '05 #1
15 5396

"Stuart" <sj*@igs.net> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
I work in a small company with developers who do not like to use "new"
features when they find the old ones sufficient. e.g. given a choice
between a class and a namespace, they'll pick class. Given a choice
between naming functions at the global scope with subsystem prefixes
(e.g. CTNode, CPNode) vs. namespaces (Time::Node, Place::Node) we'll
use the global namespace. Prefixes they understand, and prefixes are
short and do the job. Namespaces require more typing.

We understand why namespaces are good for library developers: we can
avoid name clashes. But the benefits for our own development are less
clear to me.

So here's my question:

Is there any advantage to using namespaces vs. using subsystem
prefixes? And specifically, can the compiler and linker run faster
with namespaces?

Stuart


Well, you're quite free to use whatever method you desire. But I hardly see
"CTNode" as being informative. What do the "C" and the "T" stand for? One
has to know in advance. Plus, some day you may find that your acronym fails
you, because you find the need for a "C" prefix which stands for something
else!

If your coding practices are guided by "less typing", then you're working
under rules that have little to do with accomplishing the task. A
well-designed program should have MUCH more time spent in designing than in
coding, so saving a few keystrokes shouldn't impact overall devlopment time
significantly. (Besides, you can always put "using namespace Time;"
wherever you need it, and save yourself some typing.)

And even using your "prefix" coding style, I'd want my coders to use
something like TimeNode instead of TNode, so everyone knows what the heck
the "T" stands for. Keystrokes be damned...I want to know what I'm working
with, not run around looking in manuals or asking other coders "what does
'T' stand for?"

Just my 2 cents worth (tax and tip not included).

-Howard

Jul 23 '05 #2
I abbreviated the prefixes a bit - but only a bit. The project is
nicely organized. We have a few major subsystems: "U" for utility,
"DB" for database, and the like. We have no risk of running short of
prefixes. Files and classes are organized clearly in the development
environment, so there's no huge benefit to being more explicitly clear
with the subsystem name: "TA", "QP", etc. are clear enough based on
the context. Our class names and method names are typically long
enough to be clear.

So using your naming example, what's the benefit of using the name
Time::Node
instead of
TimeNode?

Stuart

Jul 23 '05 #3
You should avoid very generic names like ' connect' or ' date' for
your classes to avoid name clashes with eventual third party libs, to
help you with this a namespace can be beneficial.

Jul 23 '05 #4
Stuart wrote:
I abbreviated the prefixes a bit - but only a bit. The project is
nicely organized. We have a few major subsystems: "U" for utility,
"DB" for database, and the like. We have no risk of running short of
prefixes. Files and classes are organized clearly in the development
environment, so there's no huge benefit to being more explicitly clear
with the subsystem name: "TA", "QP", etc. are clear enough based on
the context. Our class names and method names are typically long
enough to be clear.

So using your naming example, what's the benefit of using the name
Time::Node
instead of
TimeNode?

Stuart


The main point of a namespace is to logically group components into
modules, and it is provided at the language level so you don't have to
create workarounds for modularization. Just like functions related to
one data type are grouped into a class, functions, type definitions, and
other declarations can be grouped into namespaces to show their logical
connection or interdependence.
You could also provide several different interfaces to a namespace
depending on what users and uses you expect of it and to reduce
dependencies (and as a consequence compile times) and pollution of the
global namespace.
Just like any tool, if your team is more used to using a technique with
existing tools than one customized for a particular job, then it may be
difficult or unproductive to change the way you think from an
everything-is-global C style to a more modularized style with namespaces
and customized interfaces.
--Paul
Jul 23 '05 #5
Paul wrote:
The main point of a namespace is to logically group components into
modules, and it is provided at the language level so you don't have to
create workarounds for modularization. Just like functions related to
one data type are grouped into a class, functions, type definitions, and
other declarations can be grouped into namespaces to show their logical
connection or interdependence.
Absolutely. This is what Stroustrup says in TC++PL, and it is far more
important than the idea many programmers seem to have that the main purpose
is to avoid name clashes. That can be done by using the C-style
category_subcategory_name approach.
You could also provide several different interfaces to a namespace
depending on what users and uses you expect of it and to reduce
dependencies (and as a consequence compile times) and pollution of the
global namespace.
That serves many purposes, not the least of which is to require carful
thinking when it comes to what purpose your module really serves. This
goes beyond the worthy goal of decoupling different parts of a program.
Just like any tool, if your team is more used to using a technique with
existing tools than one customized for a particular job, then it may be
difficult or unproductive to change the way you think from an
everything-is-global C style to a more modularized style with namespaces
and customized interfaces.
--Paul


Namespaces serve very much the same function as do chapters and sections in
a book. People really should learn to use them. They help organize our
thinking.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #6
I do like your comments about the other being a workaround, but
the other developers see adding the "::" to be unnecessary extra typing
and don't see that there's anything to work around.
This just looks like language support for a convention of using
"::" to separate a subsystem prefix name from the rest of the name.
Since for years people have been prepending their own prefix name in
fairly common ways, I just don't see how using "::" instead of "_" say
improves modularization.

So I think my problem lies in understanding your middle paragraph.

- what do you mean by "provide several different interfaces to a
namespace"?
Normally we have some classes we use publically, and the rest
is all neatly hidden in the subsystem by convention or by supplying
an interface class that hides the implementation. (but the
implementation
is still in the global namespace). How can you show some but not all
of the
namespace? And how is that any better than having a class that
does the public interface and has an internal implementation?

- Everyone uses this phrase "pollution of the global namespace".
I can't find anything anywhere that explains why this matters.
Can you explain why it matters to me if I use a language feature
to resolve names of the form abc::def instead of just abc_def?
Sorry I'm so frustrated, but all I can find on the net is the mantra
with no explanation. Just because it has the word "pollution" in
it doesn't mean I'll blindly accept it on principle.
Yes I've heard the phrase a lot, but frankly I just don't understand
why I care whether the compiler has a flat list of names or
a hierarchical list of names. Especially if everyone recommends
you never do "using ThatNamespace;" so I have to use the full
name anyways.

- I suppose a similar question is why would I use
namespace { variables and routines }
instead of putting "static" in front of each of these?

Stuart

Jul 23 '05 #7
> Absolutely. This is what Stroustrup says in TC++PL, and it is far more
important than the idea many programmers seem to have that the main purpose
is to avoid name clashes. That can be done by using the C-style
category_subcategory_name approach.


Maybe my previous reply was too wordy.

I think I've completely missed the point.
How does using "::" instead of "_" improve modularization?

Stuart

Jul 23 '05 #8
Stuart wrote:
I do like your comments about the other being a workaround, but
the other developers see adding the "::" to be unnecessary extra typing
and don't see that there's anything to work around.
This just looks like language support for a convention of using
"::" to separate a subsystem prefix name from the rest of the name.
Since for years people have been prepending their own prefix name in
fairly common ways, I just don't see how using "::" instead of "_" say
improves modularization.
It's not simply a text prefix convention, it instructs the compiler that
the names with that prefix are actually considered to be a unit by the
programmer. If not only for modularization, it also helps to denote in
the code and not just by convention (or comments, which are even more
flimsy) the actual intent of the programmer.
You have two steps to access declarations in a separate namespace. One
is to provide access to the declarations (via #include on the header)
and the other is to denote what you are using out of that header via
specific or namespace-wide using declarations. The using declarations
can be nicely scoped (e.g. inside a function), unlike simply including
an entire header file of declarations.
My short answer is "because using the language feature denotes
programmer intent better than agreed conventions".

So I think my problem lies in understanding your middle paragraph.

- what do you mean by "provide several different interfaces to a
namespace"?
Normally we have some classes we use publically, and the rest
is all neatly hidden in the subsystem by convention or by supplying
an interface class that hides the implementation. (but the
implementation
is still in the global namespace). How can you show some but not all
of the
namespace? And how is that any better than having a class that
does the public interface and has an internal implementation?
I did this on a recent project involving a user interface library and
several ways to access it.
Some users will simply use the library, and need access to the
foundation-type classes like the initialization of the UI.
Some users will need more, and perhaps want to design their own widgets.

For those that just want to /use/ the UI, I have an interface that
provides access to the main listener that handles mouse and keyboard
events, a way to register action callbacks, etc, in files such as
user_interface.h and action.h
These two have a few enum types and some pure virtual classes declared,
so compile time when you include them is minimal.

For those that want to extend the UI, they can instead include
widgets.h, and action_full.h, which includes definitions to classes they
would not normally need. These two in turn include parts of the user
interface they need to compile. Including them will be more taxing on
the compiler, but you need the extra access so you must pay for it.

- Everyone uses this phrase "pollution of the global namespace".
I can't find anything anywhere that explains why this matters.
Can you explain why it matters to me if I use a language feature
to resolve names of the form abc::def instead of just abc_def?
Sorry I'm so frustrated, but all I can find on the net is the mantra
with no explanation. Just because it has the word "pollution" in
it doesn't mean I'll blindly accept it on principle.
Yes I've heard the phrase a lot, but frankly I just don't understand
why I care whether the compiler has a flat list of names or
a hierarchical list of names. Especially if everyone recommends
you never do "using ThatNamespace;" so I have to use the full
name anyways.
The pollution that people talk about means the probability of name
clashes increasing. If two components both define a "string"
class/struct that they use internally and you try to put the two
together, there will be severe compilation issues. Instead of
convoluting either environment by calling them "our_string" and
"their_string", it is better modularization to declare each in the
namespace in which it is used. Many use std::string, but it does not fit
everyone's needs, so they are free to make their own, and it is
convenient to say "string" in your code with appropriate using
declarations instead of CString or AString or Our_string.
Sorry I'm long-winded. Short answer is: so you can write identifier
names that are simple and make sense, like string, Date, and Time and
still will not clash with others.

As for shortening access to things declared in the namespace, you don't
have to include the entire namespace.
Instead of "using namespace std;" you can have "using std::string; using
std::ostream;" if those are the only two you want shortcut access to.
You have to use the full "std::string str;" if you have another 'string'
type declared, so namespaces give you a way to remove naming clashes,
obviously you do this with prepending to the actual class names in the
global namespace.

- I suppose a similar question is why would I use
namespace { variables and routines }
instead of putting "static" in front of each of these?

Stuart


I am not sure about this one. I hope someone else in the group has a
better idea about the pros and cons of either way.

--Paul Bilnoski
Jul 23 '05 #9
> - I suppose a similar question is why would I use
namespace { variables and routines }
instead of putting "static" in front of each of these?

Stuart


I found an article on C/C++ Users Journal that explains it. If you
happen to have an account, it's from June 1998,
/C++ Theory and Practice: Partitioning with Namespaces, Part 3 by Dan Saks/

I'll summarize a little here for convenience.

First, storage class specifiers such as static or extern only apply to
functions and objects and not on type declarations, so using the unnamed
namespace is more complete than declaring them static.
Also, apparently the C++ Standard has deprecated the use of the static
keyword when declaring objects (but apparently not functions) in a
namespace scope as "the unnamed namespace provides a superior
alternative", but someone more versed in the C++ Standard will have to
verify that.

Using the unnamed namespace definition guards against duplicate
declaration of external symbols in the compilation unit. If in two
separate places programmers declare the same class (function, object,
etc) name in the same namespace name (because namespaces are not closed
to additions), they will clash. However, if either or both declare the
class name in an unnamed namespace they will each remain unique and will
not cause compilation errors because they will have unique (anonymous)
namespace identifiers included as part of the identifier in the
compiler's symbol table.
Jul 23 '05 #10
GB
Stuart wrote:
I do like your comments about the other being a workaround, but
the other developers see adding the "::" to be unnecessary extra typing
and don't see that there's anything to work around.


I generally wrap most of my cpp file in a namespace like this:

#include <whatever>

namespace SubSys {

void MyImpFunc() {
}

/* etc. */

}

so that I don't have to type the prefix or the :: for my own functions
defined in that particular translation unit. Similarlly for the header file.

Gregg
Jul 23 '05 #11
GB
GB wrote:
so that I don't have to type the prefix or the :: for my own functions
defined in that particular translation unit. Similarlly for the header
file.


And, of course, I didn't mean to limit this just to non-member
functions. Member functions and data members as well go into the
namespace body.

#include <whatever>

namespace SubSys {

void MyClass::MemberFunc() {
}

/* etc. */

int MyClass::_memberVar;
}

Gregg
Jul 23 '05 #12
Stuart MacMartin wrote:
Absolutely. This is what Stroustrup says in TC++PL, and it is far more
important than the idea many programmers seem to have that the main
purpose
is to avoid name clashes. That can be done by using the C-style
category_subcategory_name approach.


Maybe my previous reply was too wordy.

I think I've completely missed the point.
How does using "::" instead of "_" improve modularization?

Stuart


In many ways, there isn't a whole lot of difference. The '_' approach is a
convention which facilitates the hierarchical organization of identifiers
according to their names. C++ namespaces are a formalization of this
concept built into the language. Among the advantages they offer are
scoping and abbreviation. The primary "hard" technical advantage to
namespace scoping is to prevent or resolve name collisions. For me that is
secondary to the psychological advantage of restricting the number of
program entities visible in a given context.

One simple "keystroke" advantage to using namespaces over "_" is that when
you are working in a given namespace all the local symbols don't require
resolution. So
foo_bar_baz_fun1();
foo_bar_baz_fun2();
foo_bar_baz_fun3();
foo_bar_baz_fun4();
can become:
namespace foo {
namespace bar {
namespace baz {
fun1();
fun2();
fun3();
fun4();
}
}
}

If you use foo::bar::baz::fun1(); a lot in a given scope you can employ a
using declaration:

using foo::bar::baz::fun1();
fun1();

It's best to introduce non-local symbols into the smallest possible
enclosing block. Depending of the tradeoffs there are times when it may
even make sense to to have a using directive:

using namespace foo::bar::baz;

One example of where I find that approach useful is with a math library I
have which contains many templated operands and associated overloaded
operators. I can simply pull the whole namespace in, and "do math" without
having to worry about introducing each symbol individually. I do this
within a function block rather than at the namespace level, in order to
prevent namespace pollution. In most cases, however, I prefer to either
introduce the fully qualified identifier with a using declaration, or
simply use it in it's long form.

Another convention I have adopted is to synchronize my namespace names with
my directory names. I've taken to calling the result a package. Take a
look at www.openscenegraph.org for an example of what I'm talking about.
They use the term 'library' instead of 'package'.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #13
Steven T. Hatton wrote:
Stuart MacMartin wrote:
Absolutely. This is what Stroustrup says in TC++PL, and it is far more
important than the idea many programmers seem to have that the main
purpose
is to avoid name clashes. That can be done by using the C-style
category_subcategory_name approach.


Maybe my previous reply was too wordy.

I think I've completely missed the point.
How does using "::" instead of "_" improve modularization?

Stuart

[snip]

BTW, this is a very thought provoking, and challenging question. Thanks for
asking.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #14
> So using your naming example, what's the benefit of using the name
Time::Node
instead of
TimeNode?


Type-saving wise, I still prefer namespace. Wouldn't the :: bring up a list
of names in your IDE (that supports code assisting features)? In most cases
Time::N will be enough and the IDE will help you complete with the "ode".

ben

Jul 23 '05 #15
benben wrote:
So using your naming example, what's the benefit of using the name
Time::Node
instead of
TimeNode?


Type-saving wise, I still prefer namespace. Wouldn't the :: bring up a
list of names in your IDE (that supports code assisting features)? In most
cases Time::N will be enough and the IDE will help you complete with the
"ode".

ben

I suspect that won't be much different for Time_N. Nonetheless, I find
Time::N more expressive.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Steven Bethard | last post by:
In the "empty classes as c structs?" thread, we've been talking in some detail about my proposed "generic objects" PEP. Based on a number of suggestions, I'm thinking more and more that instead of...
24
by: Marcin Vorbrodt | last post by:
Here is an example of my code: //Header file #include <vector> using std::vector; namespace Revelation { // class definitions, etc... // class members are of type std::vector }
2
by: Mike Morse | last post by:
What see sample that show xs:element where the xs namespace = http://www.w3.org/2001/XMLSchema However, I see another example with xsi: where xsi = http://www.w3.org/2001/XMLSchema-instance ...
3
by: Jim Heavey | last post by:
Trying to get the hang of Namespaces. I have primarly developed in VB and am transitioning to C# and the .Net Environment. I have worked a bit with Java as well in school about a year or so ago....
17
by: clintonG | last post by:
Using 2.0 with Master Pages and a GlobalBaseClass for the content pages. I understand the easy part -- the hierarchical structure of a namespace naming convention -- but the 2.0 IDE does not...
11
by: Random | last post by:
I'm confused about the proper use and usefulness of namespaces. I beleive I understand the purpose is so the developer can put classes within namespaces to essentially organize your code. And I...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.