Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!olivea!uunet!lotus!lotus.com!robertk From: robertk@lotatg.lotus.com (Robert Krajewski) Newsgroups: comp.std.c++ Subject: Re: "module" facility for top-level namespace control Summary: What's wrong with referential transparency Message-ID: Date: 9 May 91 16:19:00 GMT References: <1991Apr29.174033.29627@alias.com> <1991Apr30.202357.13791@kestrel.edu> <1991May1.192611.20568@kestrel.edu> <1991May7.230444.23042@alias.com> Sender: news@lotus.com Distribution: comp.std.c++ Organization: /homes/robertk/.organization Lines: 96 In-Reply-To: rae@alias.com's message of 7 May 91 23:04:44 GMT In article <1991May7.230444.23042@alias.com> rae@alias.com (Reid Ellis) writes: From: rae@alias.com (Reid Ellis) Lines: 33 I wrote: |Why don't we simply use a syntax which already evokes this concept -- |using "extern"? | |I don't know if another keyword after the extern is necessary, or |simply the name of the enclosing scope. Something like the following? | |extern NIH { |#include |}; Scott Layson Burson writes: |Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct |is rendered unambiguous by the `{'. So this objection is invalid. Robert Krajewski writes: |What about this one ? | |#define NIH "C" Is this a valid objection? Anything can be #define'd to anything. I wouldn't think that possible preprocessor abuse would be a problem unique to this situation. True. I guess what troubles me is this: most of the other cases of preprocessor usage normally still have reasonable results. For example, if I write foo = c + 1; and c is #defined to something, I can still assume that c is some kind of expression (even though that's not guaranteed either). I want a language where the compiler itself has final say on the semantics, and is NOT always at the mercy of the preprocessor. (Called me a starry-eyed dreamer.) That's why const quantities and inline functions were adopted; the preprocessor is just too damned weak and can't really talk to the compiler. I'm just worried about playing preprocessor games with namespace operations, where referential transparency is very important. For example, in Lisp, (use "FOO") and (use *foo-package*) are easy to understand without too much context, because rules of evaluation are always the same, even for relatively esoteric namespace operations. Consistency allows you to write code that does the same thing without regard to context, even if it doesn't make it easier in tricky cases. One suggestion would be that extern could only take a literal string for the namespace spec. extern "NIH" would be legal, and it could not be hijacked by a preprocessor's #define. extern NIH would be valid *only if* NIH was defined in the preprocessor. If I saw the code extern NIH { then I could conclude I would have to be very careful about redefining NIH. The only problem with this restriction is that certain strings would have to be reserved -- like "C", for example. Other compilers support other strings, like "Pascal". Another consistency issue is: What is really getting defined here ? The :: operator opens up the scope based in an identifer, not a string. A class definition's first `parameter' is an identifier. An identifier is just a token, so it is subject to all the preprocessor games described above. (You Can't Win.) Of course, if there was another keyword, we could stop fooling with strings and attach a `namespace' property to identifiers, just as we can attach a class property with class, a variable (lval) property though various declarations and definitions, and so on. An identifier call can only have one kind of property, and that's important if you want :: to be applicable to this new namespace concept as well as classes. NIH cannot denote both a namespace and a class, because the NIH::foo() would be ambiguous if it was possible. C++ parsers and users are forced to jump through hoops because new keywords are taboo. I especially cringe at proposals where a new feature is introduced and denoted by some meaningless concatenation of old keywords -- they don't make sense in English, and render the language even harder to parse. I contend that the proposed namespace feature is powerful and novel enough, and raises enough consistency/ambiguity issues, to seriously warrant a new keyword.