Topic: Namespaces and naming conventions
Author: "Mark Rodgers" <mark.rodgers@xtra.co.nz>
Date: 1997/09/15 Raw View
Mark Wilden <Mark@mwilden.com> wrote in article
<34146A2F.993@mWilden.com>...
> Brad Daniels wrote:
> >
> > I'm wondering, though, whether namespaces should supplement naming
> > conventions on identifiers, or replace them entirely.
>
> I like namespaces a lot, too, and one reason is that I don't have to use
> naming conventions to avoid clashes. In general, I avoid using
> declarations and directives altogether (except in implementation files)
> and simply fully qualify identifiers.
>
> So in your example, I'd just say
>
> McFoo::DoSomething();
I would like to agree. I would love to just use namespaces and
avoid naming conventions. Unfortunately it's not so easy since the
preprocessor has no respect for namespaces and certain companies
tend to use the preprocessor rather aggresively.
I just typed
grep "#[ ]*define" win*.h | wc
and got the result
7221 29769 369413
That's over 7200 potential clashes with your names that you have to
worry about and 7200 good reasons to still use naming conventions.
Even if you don't worry about macros that are all in uppercase then
there are still over 1100 potential clashes.
Now this raises and interesting question: how many macros are there
in the draft standard. I know that it includes the standard C macros
such as EXIT_SUCCESS/EXIT_FAILURE. What else is there? Was there any
thought given to converting these to C++ style and incorporating them
into the std namespace:
namespace std {
const int EXIT_SUCCESS = //... an implementation defined value.
}
Was it just too much like hard work to specify such things or too
incompatible?
--
Mark
mark.rodgers@xtra.co.nz
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Brock Peabody <npcis@pitton.com>
Date: 1997/09/17 Raw View
James Kuyper wrote:
... <snip> ...
> > using Wcount = Widget::count; // count is renamed to Wcount
...<snip>...
> Couldn't you achieve a similar effect by declaring wombat to be a
> function pointer?
Similar, yes, but what if Widget::count is an inline function, then
calling Wcount would require function call overhead, while Widget::count
(might)not.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1997/09/10 Raw View
David R Tribble wrote:
...
> It's too late for C++, but suppose namespaces had syntax for renaming
> (or 'aliasing') members of namespaces, e.g.:
>
> using wombat = Widget::xyzzy; // xyzzy() is renamed to wombat()
> using Wcount = Widget::count; // count is renamed to Wcount
>
> Or perhaps:
>
> using namespace Widget
> { // Aliases...
> wombat = xyzzy;
> Wcount = count;
> }
>
Couldn't you achieve a similar effect by declaring wombat to be a
function pointer?
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/09/11 Raw View
I (David R Tribble) suggested:
>...
>> It's too late for C++, but suppose namespaces had syntax for renaming
>> (or 'aliasing') members of namespaces, e.g.:
>>
>> using wombat = Widget::xyzzy; // xyzzy() is renamed to wombat()
>> using Wcount = Widget::count; // count is renamed to Wcount
>>
>> Or perhaps:
>>
>> using namespace Widget
>> { // Aliases...
>> wombat = xyzzy;
>> Wcount = count;
>> }
>>
James Kuyper <kuyper@wizard.net> responded:
> Couldn't you achieve a similar effect by declaring wombat to be a
> function pointer?
That's a partial solution, since you can then use 'wombat()' to invoke
the 'Widget::xyzzy()' function. But you still have the problem that
'xyzzy()' is ambiguous, still referring to both 'Widget::xyzzy()' and
'Foobar::xyzzy()'. Using function pointers forces you to use pointers
for every ambiguous name in all of their parent classes if you want to
disambiguate all cases.
My renaming suggestion would give 'Widget::xyzzy()' another name (an
alias) of 'wombat()' and effectively hide the original name 'xyzzy()'.
That would then free up (i.e., disambiguate) 'xyzzy()' in the symbol
table to be visible only as 'Foobar::xyzzy()'.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/09/12 Raw View
Brad Daniels <brad.daniels@missioncritical.com> wrote in article
<34144b5a.273866718@news1.alterdial.uu.net>...
> This is more a discussion of how to use a new feature rather than a
> discussion of the feature itself, so perhaps it should be in
comp.lang.c++.
> I think it's relevant enough, though, so I'll try here first.
> [ When to use namespaces, and when naming conventions ]
Lakos, In "Large Scale C++ Software Design" suggests (I don't have the book
here right now, so any mistake is my own) using a unique prefix for the
global identifiers in each library, and a namespace for each company's
suite of libraries.
I suspect that as namespaces see broader use, they'll be more likely to
migrate down to the library, or even component (.h) level.
The unnamed namespace is a greate tool for preventing collisions between
names of "local" classes.
Naming conventions are still important. If I want to call somebodys
cookbook function, its nice if I don't have to do a lookup to determine
which of the following function names is correct: stirsoup, stir_soup,
StirSoup, stirSoup, strsp. It is common to differentiate between "major
categories" of identifiers such as namespaces, type names, object names and
function names. Others advocate including significant type information in
data names (see Hungarian notation).
> As a side issue, I've gotten into an argument with one of the people here
> over how to combine names in subclasses. My inclination is to treat the
> name of the subclass as an adjective modifying the base class, while his
> approach is to append components to the base name for the purpose of
making
> the names sort together when generating an alphabetical list of
> identifiers. I also believe in omitting base class information from the
> name entirely when it makes sense. For example, I might write:
>
> class Animal {...};
> class LeglessAnimal : public Animal {};
> class LargeLeglessAnimal : public LeglessAnimal { ... }
> class Python : public LargeLeglessAnimal {..}
>
> Where for the same hierarchy, he'd say:
>
> class Animal {...};
> class AnimalLegless : public Animal {};
> class AnimalLeglessLarge : public AnimalLegless { ... }
> class AnimalLeglessLargePython : public AnimalLeglessLarge {..}
>
> I'd like to hear some thoughts (maybe by e-mail) as to which convention
is
> really "better". The latter approach provides some concrete benefits in
> terms of automation and grouping related classes, while the former makes
> discussing and documenting the concepts less unwieldy.
I strongly prefer the former convention. If the leaf class is named
Python, in the future I can include Scary as a base class, and client code
will almost certainly continue to work with just a recompile (no client
source changes).
If I had write access to all of the client code (strongly implies I'm not a
library vendor) and good tools for global search and replace and other used
and usefull tools which took advantage of the second naming convention I
might consider it.
The second does let all animal names sort together. However a simple
topological sort can do this for you anyway (given child/parent
relationships).
I hate to use MFC as an example of great class design, but I certainly
prefer the name CButton to CObjectCmdTargetWndButton. (I also don't want
to be too hard on MFC. It is a good example of putting a lightweight C++
wrapper around non-OO code).
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: brad.daniels@missioncritical.com (Brad Daniels)
Date: 1997/09/08 Raw View
This is more a discussion of how to use a new feature rather than a
discussion of the feature itself, so perhaps it should be in comp.lang.c++.
I think it's relevant enough, though, so I'll try here first.
I've liked the concept of namespaces ever since I first heard about them,
but it wasn't until I read the section on "using" declarations that I came
to really understand what they're for. Now that I do, I'm really jazzed
about using them extensively. I always liked the way you have to import
names into Modula or Ada code, and adding the ability to enforce that kind
of discipline in C++ is a very Good Thing.
I'm wondering, though, whether namespaces should supplement naming
conventions on identifiers, or replace them entirely. For example, say your
naming convention is to precede every global identifier with the characters
"Mc". You have a header, mc_foo.h, that defines a number of foo-related
classes and functions. Before namespaces, you'd have something like:
class McFoo { ... };
class McSubFoo : public McFoo { ... };
void McDoSomethingToFoo();
etc.
After namespaces, you could put all of the above into the "McFoo"
namespace. The question is, what should I do with the names at this point?
I see two basic approaches: I can leave the names alone to minimize name
conflicts when people do a "using namespace McFoo", or I can get rid of my
prefixes and maybe my suffixes with something like:
namespace McFoo {
class Foo { ... };
class Sub : public Foo { ... };
void DoSomething();
etc.
}
The above may result in more naming conflicts, but that fact would simply
encourage someone to do individual "using" declarations instead of just
using the whole namespace. What exactly was the original intent? How have
people actually used namespaces?
As a side issue, I've gotten into an argument with one of the people here
over how to combine names in subclasses. My inclination is to treat the
name of the subclass as an adjective modifying the base class, while his
approach is to append components to the base name for the purpose of making
the names sort together when generating an alphabetical list of
identifiers. I also believe in omitting base class information from the
name entirely when it makes sense. For example, I might write:
class Animal {...};
class LeglessAnimal : public Animal {};
class LargeLeglessAnimal : public LeglessAnimal { ... }
class Python : public LargeLeglessAnimal {..}
Where for the same hierarchy, he'd say:
class Animal {...};
class AnimalLegless : public Animal {};
class AnimalLeglessLarge : public AnimalLegless { ... }
class AnimalLeglessLargePython : public AnimalLeglessLarge {..}
I'd like to hear some thoughts (maybe by e-mail) as to which convention is
really "better". The latter approach provides some concrete benefits in
terms of automation and grouping related classes, while the former makes
discussing and documenting the concepts less unwieldy.
- Brad
----------------------------------------------------------------------------
Brad Daniels | Was mich nicht umbringt macht mich hungrig.
Mission Critical Software | - Otto Nietzche
Standard disclaimers apply | (Friedrich's corpulent brother)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Mark Wilden <Mark@mwilden.com>
Date: 1997/09/09 Raw View
Brad Daniels wrote:
>
> I'm wondering, though, whether namespaces should supplement naming
> conventions on identifiers, or replace them entirely.
I like namespaces a lot, too, and one reason is that I don't have to use
naming conventions to avoid clashes. In general, I avoid using
declarations and directives altogether (except in implementation files)
and simply fully qualify identifiers.
So in your example, I'd just say
McFoo::DoSomething();
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/09/10 Raw View
brad.daniels@missioncritical.com (Brad Daniels) wrote:
> I'm wondering, though, whether namespaces should supplement naming
> conventions on identifiers, or replace them entirely.
> ...
>
> namespace McFoo {
> class Foo { ... };
> class Sub : public Foo { ... };
> void DoSomething();
> }
>
> The above may result in more naming conflicts, but that fact would simply
> encourage someone to do individual "using" declarations instead of just
> using the whole namespace. What exactly was the original intent? How have
> people actually used namespaces?
One of the original goals of namespaces was to reduce the possibility of
name conflicts when using multiple third-party libraries. For example,
"Widgets Inc" puts all of its library functions and variables into
namespace 'Widgets' while "Foobar Ltd" puts all of its names into
namespace 'Foobar'. Now you can import both libraries and not worry about
'Widgets::xyzzy()' colliding with 'Foobar::xyzzy()'.
Or at least that's true in theory. If you use 'using' directives for both
libraries, you still get a collision. To disambiguate, you must prefix the
names with their namespace, e.g. 'Foobar::xyzzy()'.
Of course, this was already easily accomplished by ensuring that all
variables and functions were members of classes (static or otherwise)
and giving the class a suitably unique name, e.g. 'FoobarAction' or
'WidgetWindow'. The drawback is that you _had_ to use the class prefix
whether you had a name collision or not. And then there's the problem of
some companies not using a prefix that was unique _enough_ (such as, ahem,
Microsoft using a 'C' prefix for all of its MFC class names).
So what we really wanted was a way to _rename_ members within a namespace
when we imported the namespace. So, for example, we could rename the
'Widget' version of 'xyzzy()' to 'wombat()', giving us two names that
no longer collide, namely 'Widget::wombat()' and 'Foobar::xyzzy()'.
Unfortunately, we can't do that with namespaces, so they really don't
solve the original problem of name collisions. So my advice is to stick
with the time-honored practice of using unique prefixes (or suffixes)
to prevent name collisions. Whether you use namespaces or not.
It's too late for C++, but suppose namespaces had syntax for renaming
(or 'aliasing') members of namespaces, e.g.:
using wombat = Widget::xyzzy; // xyzzy() is renamed to wombat()
using Wcount = Widget::count; // count is renamed to Wcount
Or perhaps:
using namespace Widget
{ // Aliases...
wombat = xyzzy;
Wcount = count;
}
The compiler then effectively substitutes 'Widget::xyzzy' whenever it
encounters 'wombat'. (The user can still refer to either 'Widget::wombat'
or 'Widget::xyzzy' if he wanted to be specific.) This simplifies coding
and doesn't place any extra burden on the linker.
--------------------. BEA Systems, Inc. ,-. +1-972-738-6125 Office
David R. Tribble \ ,------------------' \ +1-972-738-6111 Fax
http://www.beasys.com `-' Dallas, TX 75248 `-----------------------
david.tribble@noSPAM.beasys.com http://www.flash.net/~dtribble
-------------------------------------------------------------------------
Support the anti-Spam amendment, join at http://www.cauce.org/
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]