Prev: Is there any standard/guarantees for exception safety in STL operations?
Next: Does ternary conditional operator bind the order of evaluation?
From: Keith H Duggar on 31 Jul 2010 23:48 On Jul 30, 10:23� pm, Walter Bright <newshou...(a)digitalmars.com> wrote: > Keith H Duggar wrote: > > On Jul 29, 9:15 am, Walter Bright <newshou...(a)digitalmars.com> wrote: > >> Why do namespaces fail to resolve this issue (aside from the > >> preprocessor)? > > > For one there is a need for automatically generating unique > > easy to use one-off names for helper/detail functions etc. > > Currently anonymous namespaces do this per translation unit. > > So I can without fear use short generic names for helpers > > etc for example: > > > a.cpp > > namespace { > > void dump ( ) { ... } > > } > > > b.cpp > > namespace { > > void dump ( ) { ... } > > } > > > if both a.cpp and b.cpp are included at the bottom on the > > .hpp file then when that .hpp is eventually included in some > > .cpp translation unit there will be name clashes. > > > The problem turns from annoying to dangerous when there are > > overloaded helper/detail functions because then instead of > > getting ambiguity errors your code just silently changes. > > Thanks, that's pretty much what I thought. The problem is that > C++ namespaces are not closed, in that later on the namespace's > name space can be added to. I feel this is a serious error in > the design of namespaces, but fixing that would be enormously > easier than implementing exported templates. > > (After all, one cannot add to a function, struct, enum, etc., > after its closing brace.) Judging from my own experience and looking at "professional" libraries such as STL, Boost, and many others, it seems that open namespaces are very useful. Perhaps instead of throwing them out we just need a way to optionally create closed ones. Given the C++ aversion to new keywords maybe something like: namespace Foo [ ] namespace Foo ! { } namespace Foo = { } ;-) However, open/close is not the only problem demonstrated by my example. In fact the primary problem that I see is how to enable support for short partially qualified names without clashes? A C++ translation unit provides lexical isolation making this possible: a.cpp ; namespace { void dump ( ) { ... } } void aFoo ( ) { ... dump() ... } b.cpp ; namespace { void dump ( ) { ... } } void bFoo ( ) { ... dump() ... } How do we achieve the same convenience without such lexical barriers as that imposed implicity by a translation unit? In other words I don't want to have to write this: a.hpp : (cause it's in one "java like" file now) namespace a_detail { void dump ( ) { ... } } void aFoo ( ) { ... a_detail::dump() ... } Note also the translation unit provides lexical isolation without nesting aFoo into an additional namespace layer. Ie I don't want to be forced into this either: a.hpp : (cause it's in one "java like" file now) namespace a_detail { namespace { void dump ( ) { ... } } void aFoo ( ) { ... dump() ... } } using a_detail::aFoo ; > > And, no, forcing users to generate their own unique names for > > helper namespaces (ala private_someunique) and requiring them > > to prefix throughout and/or telling them they should just nest > > everything into their already unique class name (ala Java) are > > not acceptable "solutions". > > In a sensible implementation of imports, the modules being > imported must each exist in their own, closed, name spaces. > So, one way or another, you'll need to name each source > module with a unique name. Is the D module and import system close to your view of ideal? What, if anything, would you change about it? KHD -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Timothy Madden on 1 Aug 2010 08:49 Walter Bright wrote: > Timothy Madden wrote: >> Walter Bright wrote: [...] > > I am not on the Committee and do not speak for it, but given the history of > export, I expect that the members will not give the time of day to someone > simply arguing for export. A practical implementation demonstrating it's > a good > idea would be the only thing that'll get an audience. Keep in mind that > the only > existing implementation failed to prove it's a good idea. Yeah I was afraid of that ... :( Anyway I find that the existing implementation did not go for the whole thing, as it still requires sources for the template instantiation, and that compiles an entire .cpp file, not just the pre-parsed template source. I hear they also do this recursively ?? So yes, the existing implementation is not a very good example of export... I still wonder why they considered the symbol tables too large and went for this approach. The point is however that to keep export the committee would need to see it implemented and useful, and to have it implemented I would like it kept in the language :) If only I were in high school again and have as much time as in a summer holiday. Thank you, Timothy Madden -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Walter Bright on 1 Aug 2010 14:53 Keith H Duggar wrote: > On Jul 30, 10:23� pm, Walter Bright <newshou...(a)digitalmars.com> > wrote: >> Thanks, that's pretty much what I thought. The problem is that >> C++ namespaces are not closed, in that later on the namespace's >> name space can be added to. I feel this is a serious error in >> the design of namespaces, but fixing that would be enormously >> easier than implementing exported templates. > Judging from my own experience and looking at "professional" > libraries such as STL, Boost, and many others, it seems that > open namespaces are very useful. Yes, they are seductively useful. There were a lot of proposals for changes in the D module system that would have required being able to inject more names into an existing name space. We killed those proposals with prejudice. Injecting names into a scope violates about every principle of encapsulation I've ever heard of. It makes for code that has uncontrollable behavior, in that in order to understand what it does, you have to look at the *whole project* rather than just that module. It means your carefully constructed module can be sabotaged by unrelated modules. A key element to successful module design is making the meaning of the symbols in it *independent* of the context that imports it. The C++ model of #include, extending namespaces, ADL, friends, make for poor control over encapsulation and modularity. This may not be fixable, as (as you say) so much code has come to rely on it. (Note I am using the terms module, import, and namespace rather interchangeably here.) > However, open/close is not the only problem demonstrated by > my example. In fact the primary problem that I see is how to > enable support for short partially qualified names without > clashes? That's an excellent question. In D, the degenerate case where the name is unique among all the modules in scope is the obvious, trivial case. When the names are not unique, and the overloading is disjoint, it also works. If the overloads are not disjoint, there is an ambiguity error and qualifying the names becomes necessary. There's much more detail on how this works here: http://www.digitalmars.com/d/2.0/hijack.html The anti-hijacking design is, as far as I know, unique to D and has been very successful. > Is the D module and import system close to your view of ideal? I'm very satisfied with it. > What, if anything, would you change about it? The order that a module's static constructor runs is controlled by the graph of how modules import other modules, in a depth-first manner. Trying to figure out the right thing to do when the graph contains cycles is problematic, though. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Walter Bright on 1 Aug 2010 15:48 Timothy Madden wrote: > If you want instantiation on two subsets of object files at the same > time you get to the locking problem ... :) I meant by global database that it's global to the project, rather than global for your network. Hence, there is no locking problem. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Seungbeom Kim on 2 Aug 2010 21:48
On 2010-08-01 22:53, Walter Bright wrote: > > Injecting names into a scope violates about every principle of encapsulation > I've ever heard of. It makes for code that has uncontrollable behavior, in that > in order to understand what it does, you have to look at the *whole project* > rather than just that module. It means your carefully constructed module can be > sabotaged by unrelated modules. I have never thought of namespaces as a real encapsulation mechanism, even though they may be closely related to one, such as modules. They are solutions to the common problem of having to prefix names to avoid name clashes. They don't provide any access control, nor do they provide abstraction in place of hidden details, either. For what needs to be hidden or protected from outside, you have classes with private parts. "Namespaces is a mechanism for expressing logical grouping." - Bjarne Stroustrup, TC++PL sp.ed. I think they are good for what they are designed for. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |