Topic: About namespaces


Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 5 Jan 1995 20:43:34 GMT
Raw View
In article <D1wD1w.E06@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:

>>>If the reasoning (*) (that repeating the declararion of an already declared
>>>member of a namespace is not an addition of a name) is correct
>>>then the current rules would already allow implementing members of classes
>>>inside a namespace.
>
> That is not intended.

So you confirm that it is not totally clear that my reasoning is invalid ?
IMO this calls for a clarification of wording of [r.3.3.1.3].

>>I agree.  I do not find this to be an "extension" to the C++ language.
>>It strikes me as a valid interpretation of the passages you cite.

Having related parts of [r.3.3.1.2] in mind:
 All namespaces with the same namespace-name in the same
 scope are considered part of the same namespace.
 ...
 A namespace-definition or a namespace-alias-definition is a declaration.
 ...
 Members of a namespace can be defined within that namespace.
 Members of a named namespace can also be defined outside their namespace
 using explicit qualification. In that case, the definition from the point
 of the qualification until the end of the declaration is considered
 in the scope of the namespace.

and of [r.3.3.1.3]:
 For purpose of name lookup, the scope of a class is a namespace.
 ...
 Qualification and using apply to classes exactly as to (other) namespaces.

The original sentence in [r.3.3.1.3]:
 A namespace that is a class cannot have added names
 by further namespace declarations.

should be clarified in one of two opposite directions by making clear
what a class is in respect to related parts in the definition of namespaces.
Eg:
[a]
 Contrary to other namespaces, a namespace that is a class
 cannot have added names by further namespace-definitions.
 All namespaces that have the same namespace-name as the class
 and are in the same scope are considered part of the same namespace.
 Members of a class can be defined within the namespace of that class.
 Members of a class can also be defined outside their namespace
 using explicit qualification. ...
[b]
 Contrary to other namespaces, a namespace that is a class
 cannot have added names by further namespace-definitions.
 Contrary to namespaces that are not a class,
 there may not be namespaces that have the same namespace-name as the class
 and are in the same scope.
 Contrary to members of a namespace that is not a class,
 members of a class can not be defined within the namespace of that class.
 Members of a class can only be defined outside their namespace
 using explicit qualification. ...

[a] contains 1 execption ('Contrary to ..') whereas [b] contains 3 'contrary'.
Now tell me which rule is easier to understand or explain ?
As you may have guessed I would prefere [a] :-)


> Don't be logical. :-)

To me there is no question that that it would be better (more consistent,
better readable) to have [a]. So I'm not arguing that way. The committee
tries to prevent changes over changes - note: IMO this is a good thing!
Being logical I try to show that they can't get around changing the wording
(to make clear what they 'want').
This is my chance to let them clarify it towards the direction I prefere :-)


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: ghogenso@u.washington.edu (Gordon Hogenson)
Date: 3 Jan 1995 20:39:15 GMT
Raw View
schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:


>Repeated questions and discussions in this newsgroup have shown that
>implementing the members of a class inside a namespace is a virulent idea.

>I totally agree. It seems that such a thing was not thought about
>when namespaces were introduced. [r.3.3.1.3 (April93)] relates
>the old feature of classes to the new feature of namespaces.
>But when I look a the wording, I do not find it clear that
>implementing members of classes inside a namespace is forbidden.

> For purpose of name lookup, the scope of a class is a namespace.
> ... A namespace that is class cannot have added names
>     ^^^^^^^^^^^^^^^^^^^^^^^^^
> by further namespace declarations.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>I can't find the definition of what a namespace declaration is.
>But maybe with [r.3.3.1.2] (A namespace-definition .. is a declaration.)
>a namespace-definition is meant here. To obey the One-Definition-Rule
>of a class the mentioned "further namespace declaration" cannot be
>a further (another) declaration/definition of the (same) _class_.
>So it must be a simple namespace. This results in

> class A {
> public:
> void m ();
> };
> namespace A {   // legal to write a further namespace-definition
> void f (); // ERROR: trying to add 'f' to namespace 'A' that is a class
> void m (); // ok, not _adding_ a new name to namespace 'A'
>    //     but _repeating_ an old name (*)
> void m () // ok, not _adding_ a new name to namespace 'A'
>    //     but _repeating_ an old name (*)
> {}
> };

>If the reasoning (*) (that repeating the declararion of an already declared
>member of a namespace is not an addition of a name) is correct
>then the current rules would already allow implementing members of classes
>inside a namespace.
>So allowing implementing members of classes inside a namespace would _not_
>realy be a new feature, but a _clarification_ of what the already introduced
>feature of namespaces means regarding classes.
>And OTOH disallowing it would be the introduction of _another_ _new_
>_restriction_ in the question of 'in what way is a class a namespace'.

I agree.  I do not find this to be an "extension" to the C++ language.
It strikes me as a valid interpretation of the passages you cite.
To be sure, allowing member templates was a much greater "extension"
to the language than is this, but this was called "minor" by Josee
Lajoie in a recent issue of C++ Report.

>Ulf Schuenemann

>PS: When the wording of [r.3.3.1.2] has changed until April93, my
>argumentation may have become incorrect.

Would anyone care to post the current references here?  We appear to be
arguing in the dark.  (Would this violate the secrecy rule?)

For the practical-minded, allowing implementation of members of classes
in namespaces is a great notational improvement.  For the aesthetically
minded (like myself), not only is the syntax beautified, but (perhaps
more important to some) the "is-a-kind-of" relationship between a "class
namespace" and an ordinary namespace would be cemented.  A class
declaration 'X' creates a namespace
X'.  One ought therefore to EXPECT to treat it as a namespace *as far
as is possible and practical*, unless there is a sufficiently good reason
for disallowing some feature of a namespace to apply to a class namespace.
The burden should fall on those who want to *restrict* the application of
namespace semantics to class scopes, to explain why classes should not
inherit the behavior of ordinary namespaces.

If it were to be implemented, there are some details which would need to be
worked out.  I ask for opinions on the following:

1. I believe the current policy is that 'classes may not have
   further names added by further namespace declarations.'
   Should 'private' helper functions be allowed ?  Probably not
   if the proposal is to have any chance of acceptance.  Allowing
   private helper functions smells too much like an extension.
   If the standard were changed so that "Names added to a class
   namespace by further namespace declarations are private",
   What should the scope of these private members be?  Local
   to that namespace declaration?  Local to that namespace declaration
   and ones that follow it?  Probably local to that namespace declaration, but
   duplicates in different namespace declarations for the same
   namespace link to the same object (like "extern" and not "static").
   I am inclined to stick with the original restriction for the reason that
   functions defined in the class scope and functions defined
   elsewhere should probably have equal access to all members of
   the class.  But I don't know.  It may not be that important, in
   which case the restriction would be unnecessary nannyism.

2. There is a strong implication that namespaces should be allowed to
   be templates.  This, too, will probably smell too radical.  But,
   I believe that what is allowed for classes should also be allowed for
   templates, by DEFAULT.  Allowing

    class X { /* ... */ };
    namespace X { /* ... */ };

   but not

   template <class T> class X { /* ... */ };
   template <class T> namespace X { /* ... */ };

    would be a serious mistake.

   There is a danger for the committee in being *too conservative*,
   so much so that users respond with "What, you mean I can't do that??"

Gordon.




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 4 Jan 1995 20:03:31 GMT
Raw View
In article <3ecclj$p5e@nntp1.u.washington.edu> ghogenso@u.washington.edu (Gordon Hogenson) writes:
>schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
>
>>Repeated questions and discussions in this newsgroup have shown that
>>implementing the members of a class inside a namespace is a virulent idea.
>
>>I totally agree. It seems that such a thing was not thought about
>>when namespaces were introduced.

 It was.

>>If the reasoning (*) (that repeating the declararion of an already declared
>>member of a namespace is not an addition of a name) is correct
>>then the current rules would already allow implementing members of classes
>>inside a namespace.

 That is not intended.

>>So allowing implementing members of classes inside a namespace would _not_
>>realy be a new feature, but a _clarification_ of what the already introduced
>>feature of namespaces means regarding classes.

 Try arguing that in the committee :-)

>>And OTOH disallowing it would be the introduction of _another_ _new_
>>_restriction_ in the question of 'in what way is a class a namespace'.

 Don't be logical. :-)
>
>I agree.  I do not find this to be an "extension" to the C++ language.
>It strikes me as a valid interpretation of the passages you cite.

>   There is a danger for the committee in being *too conservative*,
>   so much so that users respond with "What, you mean I can't do that??"

 I recommend you say that this should be allowed
during the ANSI public comment period. And get others to do so too.
Begin preparing your submission NOW. You will not have long to
respond.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 24 Dec 1994 12:43:47 GMT
Raw View
In article <3dap2l$h5r@linda.teleport.com> deef@teleport.com (Derek Foster) writes:
>
>whereas if namespaces were implemented as the author of the original post
>has suggested, you could write:
>
>namespace LongName::LongerName::LongestName
>{
>   NestedType function1()
>   {
>     return ABC;
>   }
>   NestedType function2()
>   {
>     return DEF;
>   }
>}
>
>Does anybody know if the current working paper allows this syntax?

 No, it doesn't. I argued it should. In fact, I argued
private non-virtual helper functions could be added in such
a namespace -- implementation details which would not be
visible to the client of the class, and whose introduction
is completely typesafe, in no way breaks encapsulation, and
also has the minor side effect of not triggering
cascaded recompilations.

 Unfortunately, the importance of being able to
write clear, concise, and readable code seems not to influence the bulk
of committee members as much as the need to eliminate all
"unnecessary" extensions.  (NO criticism of any individual is intended!
I think this "hackery" is a function of the committee
approach -- especially a committee with 80 people on it)
Sigh. The fact that committee time was spent discussing:

 Outer::Inner Outer::Inner::function() {}

where "Inner" is a PRIVATE type of "Outer", and decided that
this was legal (access constraints are applied AFTER the whole
declaration is read, not immediately), when in fact the
extension suggested would have obviated the need to write such
code, is somehow considered a better way to spend time than
solving multiple related problems at once.

 Pete Becker (I seem to recall) championed a reasonable
argument against being able to secretly add invisible helper
functions --  at present all functions with access can be
"tracked" down using grep, since the names of the lot of them
are known by reading the declaration in the header.

 Unfortunately, this argument does not really stand well.
Any member or friend can "pass on" access no matter what the
language rules say about friendship and access control
not being transitive.  They can do that by simply passing
pointers to the private members of the object to whatever
function they choose.

 Therefore, to track down all functions that may mutate
an object's private members already requires "recursive" descent
searching -- find the members, find what functions they grant
access to. And the namespace extension suggested has just
that property, but MORE constrained -- at least the private
helpers must reside in a known namespace. I suggest
private helpers are a BETTER solution than public, global,
functions which accept and work with pointers to private
members (when applicable, which is not always).

 I also note nested functions would assist in
reducing the number of private helpers, where such functionality
was local to a single member function.

 I have to say that even WITHOUT nesting, I find
having to write the class name in front of member function
definitions annoying and that this reduces clarity.
Much worse, a translation unit defining members of more than
one class provides no way to segregate the members visually,
so as I add members to classes A, B, and C, the definitions
tend to get tacked on to the end of the translation unit --
i.e. not in order of classes A, B, and C. Thats because I'm
too lazy to clearly delineate the boundaries with comments,
and I often do not want to bother with multiple files.

 It is a great pity, IMHO, that we can do this
with namespaces, but not classes. It will tend to
stop people using nesting because of it's long windedness,
even if it is structurally the better option.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 27 Dec 1994 17:43:00 GMT
Raw View
In article <D1BFD0.1JF@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:
|> In article <3dap2l$h5r@linda.teleport.com> deef@teleport.com (Derek Foster) writes:
|> >whereas if namespaces were implemented as the author of the original post
|> >has suggested, you could write:
|> >
|> >namespace LongName::LongerName::LongestName
|> >{
|> >   NestedType function1()
|> >   {
|> >     return ABC;
|> >   }
|> >   NestedType function2()
|> >   {
|> >     return DEF;
|> >   }
|> >}
|> >
|> >Does anybody know if the current working paper allows this syntax?
|>
|>  No, it doesn't. I argued it should.
[.. and private non-virtual helper functions..]
|>
|>  Unfortunately, the importance of being able to
|> write clear, concise, and readable code seems not to influence the bulk
|> of committee members as much as the need to eliminate all
|> "unnecessary" extensions.  (NO criticism of any individual is intended!
[.. the committee discussed Outer::Inner ..]

Repeated questions and discussions in this newsgroup have shown that
implementing the members of a class inside a namespace is a virulent idea.

[.. helper/nested functions ..]
|>  I have to say that even WITHOUT nesting, I find
|> having to write the class name in front of member function
|> definitions annoying and that this reduces clarity.
|> Much worse, a translation unit defining members of more than
|> one class provides no way to segregate the members visually,
[.. adding new members to classes ..]
|>  It is a great pity, IMHO, that we can do this
|> with namespaces, but not classes. It will tend to
|> stop people using nesting because of it's long windedness,
|> even if it is structurally the better option.

I totally agree. It seems that such a thing was not thought about
when namespaces were introduced. [r.3.3.1.3 (April93)] relates
the old feature of classes to the new feature of namespaces.
But when I look a the wording, I do not find it clear that
implementing members of classes inside a namespace is forbidden.

 For purpose of name lookup, the scope of a class is a namespace.
 ... A namespace that is class cannot have added names
     ^^^^^^^^^^^^^^^^^^^^^^^^^
 by further namespace declarations.
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I can't find the definition of what a namespace declaration is.
But maybe with [r.3.3.1.2] (A namespace-definition .. is a declaration.)
a namespace-definition is meant here. To obey the One-Definition-Rule
of a class the mentioned "further namespace declaration" cannot be
a further (another) declaration/definition of the (same) _class_.
So it must be a simple namespace. This results in

 class A {
 public:
 void m ();
 };
 namespace A {   // legal to write a further namespace-definition
 void f (); // ERROR: trying to add 'f' to namespace 'A' that is a class
 void m (); // ok, not _adding_ a new name to namespace 'A'
    //     but _repeating_ an old name (*)
 void m () // ok, not _adding_ a new name to namespace 'A'
    //     but _repeating_ an old name (*)
 {}
 };

If the reasoning (*) (that repeating the declararion of an already declared
member of a namespace is not an addition of a name) is correct
then the current rules would already allow implementing members of classes
inside a namespace.
So allowing implementing members of classes inside a namespace would _not_
realy be a new feature, but a _clarification_ of what the already introduced
feature of namespaces means regarding classes.
And OTOH disallowing it would be the introduction of _another_ _new_
_restriction_ in the question of 'in what way is a class a namespace'.


Ulf Schuenemann

PS: When the wording of [r.3.3.1.2] has changed until April93, my
argumentation may have become incorrect.
--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de





Author: deef@teleport.com (Derek Foster)
Date: 21 Dec 1994 18:42:29 -0800
Raw View
In <D0v54D.686@borland.com> pete@borland.com (Pete Becker) writes:

>>template <class T, class V>
>>template <class U>
>>return_type
>>OuterClass<T,V>::InnerClass<U>::function() { ... }
>>
>>Or whatever the ugly syntax is for nested template classes.

> This is an attempte to solve a problem that does not exist.
>Nested template classes are not allowed in C++, so there is no "ugly
>syntax" for dealing with them.
> -- Pete

Perhaps so, but ordinary template member functions are just as bad, and even
nested classes become a nightmare in constructions like:

struct LongName
{
   struct LongerName
   {
      struct LongestName
      {
        enum NestedType {ABC,DEF};
        NestedType function1();
        NestedType function2();
      }
   }
}
How are we to define these functions? They currently look like:

LongName::LongerName::LongestName::NestedType LongName::LongerName::
  LongestName:function1()
{
   return ABC;
}

LongName::LongerName::LongestName::NestedType LongName::LongerName::
  LongestName:function2()
{
   return DEF;
}

whereas if namespaces were implemented as the author of the original post
has suggested, you could write:

namespace LongName::LongerName::LongestName
{
   NestedType function1()
   {
     return ABC;
   }
   NestedType function2()
   {
     return DEF;
   }
}

Does anybody know if the current working paper allows this syntax?

Derek Riippa Foster
--
deef@teleport.com  Public Access User --- Not affiliated with TECHbooks
Public Access UNIX and Internet at (503) 220-1016 (2400-14400, N81)




Author: pete@borland.com (Pete Becker)
Date: Thu, 15 Dec 1994 17:38:15 GMT
Raw View
In article <3cfqol$63h@nntp1.u.washington.edu>, ghogenso@u.washington.edu
says...
>

>I, too, have had some grave doubts about namespaces.  It is said in
>the ANSI draft I have ( iso.ps at ftp.std.com ) that the scope of a
>class is a kind of namespace.  Stroustrup in "Design and Evolution"
>says that whatever is true of namespaces would also be true of classes,
>since the "class" abstraction is a "derivation" from the namespace
>abstraction.  But, this is not really the case, according to the
>draft standard for namespaces (again, very out of date, since the
>current WP is not publically available).  If it were the case,
>you would be able to do things like:
>
>class A { ... }
>
>namespace A {
>
>// definitions for class A
>
>}
>
>In other words, you would be able to use the namespace syntax to
>specify the scope for the definitions enclosed within it, which
>could be class definitions.
>
>This would be useful in many cases, particularly where class
>names (and/or template specifications) are long.  Writing
>
>template <class T, class V>
>template <class U>
>return_type
>OuterClass<T,V>::InnerClass<U>::function() { ... }
>
>Or whatever the ugly syntax is for nested template classes.

 This is an attempte to solve a problem that does not exist.
Nested template classes are not allowed in C++, so there is no "ugly
syntax" for dealing with them.
 -- Pete





Author: ghogenso@u.washington.edu (Gordon Hogenson)
Date: 11 Dec 1994 21:25:41 GMT
Raw View
esap@pohjanrastas.cs.tut.fi (Pulkkinen Esa) writes:

>.... And I think there should be more similarities between
>namespaces and classes... maybe namespace templates? or inherited namespaces?
>Well.. I'm not very certain if anything like this is possible/useful/
>necessary... Comments are welcome.

I, too, have had some grave doubts about namespaces.  It is said in
the ANSI draft I have ( iso.ps at ftp.std.com ) that the scope of a
class is a kind of namespace.  Stroustrup in "Design and Evolution"
says that whatever is true of namespaces would also be true of classes,
since the "class" abstraction is a "derivation" from the namespace
abstraction.  But, this is not really the case, according to the
draft standard for namespaces (again, very out of date, since the
current WP is not publically available).  If it were the case,
you would be able to do things like:

class A { ... }

namespace A {

// definitions for class A

}

In other words, you would be able to use the namespace syntax to
specify the scope for the definitions enclosed within it, which
could be class definitions.

This would be useful in many cases, particularly where class
names (and/or template specifications) are long.  Writing

template <class T, class V>
template <class U>
return_type
OuterClass<T,V>::InnerClass<U>::function() { ... }

Or whatever the ugly syntax is for nested template classes.
Faced with such syntax, many reasonable people would feel obliged
to use the preprocessor, or perhaps (sadly) avoid such powerful
constructions. (or more likely, define their functions in the
declaration).  Another advantage is that the
definition of the function within the "namespace definition" is
syntactically the same as the definition in the class declaration.
(This is not only a practical advantage, but is aesthetically
sounds, since equivalent concepts should be reflected by identical
syntax.)

With the namespace syntax, the complicated template specifications
and scope qualifications could be put in the namespace name
(namespaces would have to be allowed to be templates.  Stroustrup
is sympathetic to this, I think, based on remarks made in
"Design and Evolution").  Instead of the above you say, once, at
the top of the file,

template < class T, class V >
namespace OuterClass {
  template <class U> namespace InnerClass {
     // here put definitions like this:

     return_type function();

  }
}

The above syntax is consistent with the syntax for defining functions
which are members of namespaces.  Allowing this simply allows classes
to behave like namespaces, perfectly reasonable since "A class is a kind
of namespace."

I'm working on an example involving lists of pointers to member
functions which demonstrates the usefulness of having such
complicated templates, and compares the syntax of the definitions
using namespaces, and using the current syntax.

Disclaimer:
For all I know, though, the definitions of namespaces may have changed
considerably from the March 1994 resolutions, or I may be interpreting
these resolutions incorrectly.  There are some ambiguous phrases which
I may be interpreting incorrectly.  The syntax I propose here may in
fact already be allowed.  Section r.3.3.1.3:

"For purposes of name lookup, the scope of a class is a namespace."

Name lookup for calling functions, or for defining them as well?

Also in r.3.3.1.3,

"A namespace that is a class cannot have names added by further
 namespace declarations."

Is a class a namespace, or is "the scope of a class" a namespace?
A namespace that is a class cannot have names added by further
namespace declarations, but perhaps the
already declared names can be defined in other namespace
definitions.  I don't know how to interpret this.

Gordon J. Hogenson