-1

Header files with declarations like this:

void FooBar(System::Network::Win32::Sockets::Handle handle, System::Network::Win32::Sockets::Error& error /*, more fully-qualified param declarations... */);

are common in certain frameworks. And using declarations, which could mitigate this problem, are generally not considered kosher to use in header files because they can effect the name lookup rules for header files that are included later. typedefs inside a class that are declared private clutter up the class' namespace and the namespace of classes derived from it.

Here is a proposed solution:

using {
   // A 'using' block is a sort of way to fence names in.  The only names
   // that escape the confines of a using block are names that are not
   // aliases for other things, not even for things that don't have names
   // of their own.  These are things like the declarations for new
   // classes, enums, structs, global functions or global variables.
   // New, non-alias names will be treated as if they were declared in
   // the scope in which the 'using' block appeared.

   using namespace ::std;
   using ::mynamespace::mytype_t;
   namespace mn = ::mynamespace;
   using ::mynamespace::myfunc;

   class AClass {
     public:
      AClass(const string &st, mytype_t me) : st_(st), me_(me) {
         myfunc(&me_);
      }

     private:
      const string st_;  // string will refer to ::std::string
      mn::mytype_t me_;
   };
// The effects of all typedefs, using declarations, and namespace
// aliases that were introduced at the level of this block go away
// here.  typedefs and using declarations inside of nested classes
// or namespace declarations do not go away.
} // end using.

// Legal because AClass is treated as having been declared in this
// scope.
AClass a("Fred", ::mynamespace::mytype_t(5));

// Not legal, alias mn no longer exists.
AClass b("Fred", mn::mytype_t);

// Not legal, the unqualified name myfunc no longer exists.
AClass c("Fred", myfunc(::mynamespace::mytype_t(5));

In Java and Python individual files are treated in a special way. You can have import declarations that inject names from other namespaces into the file. These names will (well, not exactly with Python, but it's too complicated to explain here) only be visible within that file.

I think C++ needs a similar construct. The existence of the preprocessor, the #include directive, and the C++ concept of a translation unit make the implicit scoping of imported names problematic. So some I think some mechanism for explicitly scoping such temporary aliases is needed.

What problems do you foresee with this idea? If there are no problems, or the problems are very small and fixable, how would I go about submitting it as a proposal to the standards committee?

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • 6
    If you gonna fix C++, make them deprecate `#include` and introduce a proper module system instead. –  Dec 06 '10 at 20:41
  • @delnan - I don't agree. I find Java's module system to be extremely irritating and somewhat problematic in some cases. I think the implicit file scoping is an issue. I also think removing `#include` is a huge project and something is needed for sanity before that can happen. – Omnifarious Dec 06 '10 at 20:43
  • Proper/"good" module system >>> shitty module system > preprocessor and new language constructs to fix some of its problems. (Also, I'm not entirely serious) –  Dec 06 '10 at 20:45
  • @delnan: They did that with the D Programming Language (among other features). You won't be able to remove it and maintain backwards compatibility; you would have to create a new language with similar syntax (again, which is what they did with D). – Zac Howland Dec 06 '10 at 20:46
  • Let's suppose I typedef a boost::shared_ptr inside the block. Does it escape? – Winston Ewert Dec 06 '10 at 20:47
  • @Winston Ewert - Nope. The typedef name does not escape. If you want general purpose typedefs that should be generally available you'd have to declare them outside the using block. – Omnifarious Dec 06 '10 at 20:49
  • 1
    @Zac Howland: 1. That's why I said "deprecate". 2. [There was a module system proposed for C++0x](http://stackoverflow.com/questions/3596147/modules-in-c0x), but it seems like it didn't make it. 3. "(Also, I'm not entirely serious)". And btw, I admire Walter Bright for trying (and in some ways succeeding) to build a "better C++". –  Dec 06 '10 at 20:51
  • 1
    The module proposal is scheduled to be worked on for the TR2 or the next C++ version (that would be 5 years after C++0x, they wish) - like Concepts. – Klaim Dec 06 '10 at 20:54
  • 1
    If you were to submit such a proposal, the module system would probably be your worst enemy, because it solves a number of the same problems, but is much more general (and something the committee has already indicated they want to pursue), making it harder to make a good case for your proposal. – jalf Dec 06 '10 at 21:43

3 Answers3

3

The ISO/IEC JTC1/SC22/WG21 (aka C++) standards committee is close to finishing the C++0x standard; you have essentially no chance of getting this proposal into the C++0x standard.

For any proposal, you have to present the motivation for the feature, explaining why this should be added to the standard instead of the 50 other proposals contending for the privilege. (See Stroustrup's explanation in D&E - 'Design and Evolution of C++'.)

You also benefit from having an implementation in place, which is available and used, so people have hands-on experience of the feature at work. While it remains abstract and unimplemented, you run the risk of repeating the export fiasco, and the committee tries to avoid repeats of that. One advantage of this is that it helps build your constituency of people who are interested in using your feature. If you can't build such a constituency, maybe your proposal isn't worthy of inclusion in the standard.

What you've given here might be an interesting start, but it is not yet anywhere near what would be needed to get to a standard proposal. Take a look at the documents on the Open Standards web site. Consider whether you have the resources at your disposal to take this forward. The chances are that you do not, I'm sorry to say.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    @Zach: Which attitude? Standards that were successful standardized existing practice - C89 is one of the best examples of that. Standards that are not successful create on the fly - SQL is one of the best examples of that. C++ ran into problems with export - which was not implemented before being standardized. Read D&E to see what Stroustrup has to say about it; I'm echoing what he says, to a large extent. (Also: the TR1 features in C++ were based on implementation experience via Boost; the STL was based on implementation experience. They worked!) – Jonathan Leffler Dec 07 '10 at 14:05
  • @Zach: The comment about having the reosurces to take the proposal forward is pure pragmatism. Any proposed change to the standard has to be proposed by someone on the committee and carried through the committee. There are a myriad change proposals; each has to win on its merits, but its merits must be explained, and possible problems overcome, and that requires a committed advocate on the committee, able to attend meetings and deal with . – Jonathan Leffler Dec 07 '10 at 15:10
  • I just don't see how that's dynamic enough to keep up with modern languages like C#. – Zach Saw Dec 08 '10 at 00:12
  • "If you can't build such a constituency, maybe your proposal isn't worthy of inclusion in the standard." Even if you can, it still may not get included - e.g. __property keyword by Borland. – Zach Saw Dec 08 '10 at 00:14
  • "Which attitude?" - 1) Begin overly conservative in adding features to the language. 2) Not deprecating old (now largely unused) and failed features, leading to overly complicated and painfully slow compiler. 3) Committee should look into a good idea from anyone and do the work necessary to determine if it's indeed a good fit for the language (like what Microsoft is doing), rather than adopt a wait and see approach. 4) Not being proactive / dynamic (vs C#). – Zach Saw Dec 08 '10 at 00:20
  • And the list goes on. But that's a topic for another day. Not to mention that the 'committee' is made up of groups of people who have different motives and business interests. You'll end up with this, "If you want it in the standards, //you// do all the work to see if anyone would use it first." – Zach Saw Dec 08 '10 at 00:23
  • Wake up guys, look around you and tell me honestly how many C++ jobs are there vs C# / JAVA jobs? Extrapolate that trend 10 years out from now - what would we get? – Zach Saw Dec 08 '10 at 00:25
  • @Zach: sounds like you're volunteering to join the committee. Good luck. Have fun! Remember: they are volunteers. Even if they're paid by their company (and not all of them are, and some of them own 'their company'), they are volunteers who contribute a lot out of love of the language. And they have the experience of what goes wrong. And they know how much damage incompatible changes cause (answer: a lot!). So they are justifiably cautious. If you don't like it, go and implement a compiler. Then add a dozen features to see which ones work. Then remove 8 of them; add 6 more; remove 3 of them. – Jonathan Leffler Dec 08 '10 at 01:19
  • "Remember: they are volunteers" -- This ***is*** the problem then isn't it? – Zach Saw Dec 08 '10 at 01:28
  • "If you don't like it, go and implement a compiler." Microsoft's already done that with C#. Sun did that with JAVA. DigitalMars with D. So there you go. – Zach Saw Dec 08 '10 at 01:29
  • "volunteers who contribute a lot out of love of the language". In other words, you're saying it's a language created for hobbyists by hobbyists? – Zach Saw Dec 08 '10 at 01:31
  • @Zach: so, do you want a C++ standard? Are you proposing to pay for it? Or how are you going to get the standard paid for? And yes, people have implemented other languages. It is always an option. I'm done discussing with you. You need to find out more about how language standardization works (and how the process gets abused, and past successes and failures); I don't think you have a proper appreciation for the complexity or magnitude of the work. – Jonathan Leffler Dec 08 '10 at 01:32
  • "sounds like you're volunteering to join the committee." Powerful deductive capabilities you have Jonathan Leffler. Oh, world's about to end! – Zach Saw Dec 08 '10 at 01:34
  • "I don't think you have a proper appreciation for the complexity or magnitude of the work". That's the point. I don't, and these days, most people don't any more for C++ if it continues to fall behind modern languages. – Zach Saw Dec 08 '10 at 01:35
  • "so, do you want a C++ standard? Are you proposing to pay for it?" I'm saying proprietary languages are thriving much better than standardized ones at this day and age - unless the committee realises this, C++ will keep falling behind. – Zach Saw Dec 08 '10 at 01:38
  • "So they are justifiably cautious." This is where your opinion differs from mine - I'm saying they haven't got the balance right. – Zach Saw Dec 08 '10 at 01:42
  • "Or how are you going to get the standard paid for?" -- Exactly how open source software get paid for. – Zach Saw Dec 08 '10 at 01:45
3

Looks confusing to me. The difference between your using block and a regular block is that some names get out, and the rule for which is which seems fairly arbitrary, and people will come up with corner cases that don't work the way you'd expect. Nor do I see what general use this would be.

Can't you do something very much like this with a uniquely-named namespace and some using namespace::foo; statements?

The first thing you should do towards making this, or anything similar, into a standard, is to study some C++ committee documents, which will give you an idea what you will need to do. At the very least, you will need language that can be put into the standard, very good arguments why it would be a good idea, and careful consideration of the pros and cons.

The next thing is to try to get some practice with this, which means coming up with a compiler (likely a changed version of g++) that implements it, and trying to make that popular.

If you can get some real-world use going, you've got a crack at getting into the next standard, not the one currently being finalized, but the one after that. It would help if you could join the Committee, since any new feature is pretty much going to need a champion there. The good news is that they can't keep you out; the bad is that it's going to be expensive, time consuming, and often tedious.

This may sound like a lot, but you're trying to put another feature into a language overloaded with them. You're going to need a really good justification and a lot of work.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
1

You mean like how everybody just has namespaces that they reserve for implementation details? Or how you could just use a class and stick the members as private if you don't want them accessed? It's not that this idea is fundamentally wrong or bad, I just don't see the benefit. C++'s compilation model has much, MUCH larger holes that need fixing rather than a triviality like this.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • If you make them private you are cluttering the namespace of your class and all the classes derived from it. If someone refers to `string` inside a class derived from your class where you had a private typedef to `::std::string` they will end up with the compiler complaining that the type is inaccessible. The details namespaces are a little better, but if you use the same details namespace in several header files you start having cluttering issues too. – Omnifarious Dec 06 '10 at 20:53
  • @omnifarious : Check the pimpl idiom for your cluttering issues with header files : http://en.wikipedia.org/wiki/Opaque_pointer – Matthieu Dec 06 '10 at 21:07
  • @Matthieu - That idiom is fantastic, but it doesn't solve the interface problem of having a type name like `::cartoon::flintones::fred::PrePebbles::Widget` and having to use the full qualified name each time to avoid polluting any other namespaces with the name `Widget`. – Omnifarious Dec 06 '10 at 21:09
  • @Omnifarious: The point of the class is to have access modifiers, not to become a run-time object. Make a private constructor -> no derived classes. – Puppy Dec 06 '10 at 21:10
  • Can't you just use an anonymous namespace with a using directive in it? eg `namespace{ using ::far::too::many::nested::namespaces::cxx::is::not::java::type; } void foo(type&);` ? – KitsuneYMG Dec 07 '10 at 03:40