Topic: module" facility for top-level namespace control


Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 28 Apr 91 01:36:30 GMT
Raw View
In article <5281@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>In article <1358@appli.se> niklas@appli.se (Niklas Hallqvist) writes:
>>... Should we (the net) try to write a proposal
>>to the ANSI commitee before their june meeting in Lund, Sweden (at
>>least I think that's the case, some of the members will speak at
>>some seminars there, which I'll try to attend).
>
>Sure.  Why not?  I think that the x3j16 committee (and especially the
>libraries working group) would  probably thank us for it.
>
>Let me see if I can get the ball rolling a bit (and see where it goes).
>
> [proposal deleted -- see article 801]

Good Lord, Ron, this is complicated.  Constructors and destructors?
Inheritance?  I was just trying to solve a namespace problem!

I think what we're seeing here is a Whorfian effect.  The so-called
"Sapir-Whorf Hypothesis" (Sapir and Whorf were linguists) suggests
that the *words* one uses to think about something affect the *way* in
which one thinks about it.  You introduced this notation `class static
{ ... }', and then proceeded to try to think about these things as
some funny kind of class.

I don't know what others have been thinking, but this was never what I
had in mind.  All I have wanted is a way to get qualifiers onto names
in source files I have received from someone else.

In fact, after some thought I have pretty much concluded that my
favorite keyword for this construct is `namespace'.  It says exactly
what it means (unlike, alas, some others in this language).

-- Scott
Gyro@Reasoning.COM




Author: wmm@world.std.com (William M Miller)
Date: 28 Apr 91 23:15:09 GMT
Raw View
rfg@NCD.COM (Ron Guilmette) writes:
> >... Should we (the net) try to write a proposal
> >to the ANSI commitee before their june meeting in Lund, Sweden (at
> >least I think that's the case, some of the members will speak at
> >some seminars there, which I'll try to attend).
>
> Sure.  Why not?  I think that the x3j16 committee (and especially the
> libraries working group) would  probably thank us for it.

The more, the merrier!  (There's already scheduled to be a proposal from a
committee member on this topic at the Lund meeting.)

> First off, I must say that I think that the proposal should be entirely
> non-committal about the specific syntax and keywords used.
>                                         Arguing for a specific keyword
> (or set of keywords) is only likely to turn-off some members of x3j16,
> so why not just propose the feature and ask x3j16 to decide what keywords
> they want to use to express it?

Well, this sounds plausible, I suppose, but as a member of the extensions
working group, I think I speak for most of us in saying that complete
proposals, including consideration of the syntactic impact of the proposed
feature, are *much* preferable to "Here's the idea, now you go off and work
out the details" proposals.  If there is a problem with the syntax you
propose but the rest of the idea is attractive, the worst that will happen
is that you'll be informed of the problems and asked to try and solve them;
if you submit a "concept only" proposal, there's a good likelihood that it
will simply be consigned to the large pile of "good ideas" that are waiting
for someone to make into a complete proposal.

-- William M. Miller, vice chair, X3J16
   wmm@world.std.com




Author: rae@alias.com (Reid Ellis)
Date: 29 Apr 91 17:40:33 GMT
Raw View
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 <NIHCL.h>
};
     Reid
      -- still red from not seeing
      -- the "static class {} var;"
      -- option. :)
--
Reid Ellis     1 Trefan Street Apt. E, Toronto ON, M5A 3A9
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]




Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 30 Apr 91 20:23:57 GMT
Raw View
In article <1991Apr29.174033.29627@alias.com> rae@alias.com (Reid Ellis) writes:
>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 <NIHCL.h>
>};

My first reaction was Hey, this is pretty good, but look what it would
mean: the rule would have to be that *if* the name following `extern'
were not defined as a type, which is what would normally appear in
that position, *then* treat it as a namespace.  Then someone who
misspelled a type name following `extern' wouldn't find out about it
until link time, and rather indirectly at that.

Besides, the namespace construct *doesn't* mean that the stuff between
the braces is `extern'.  So I would still prefer the keyword
`namespace'.

-- Scott
Gyro@Reasoning.COM




Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 1 May 91 19:26:11 GMT
Raw View
In article <1991Apr30.202357.13791@kestrel.edu> I wrote:
>In article <1991Apr29.174033.29627@alias.com> rae@alias.com (Reid Ellis) writes:
>>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 <NIHCL.h>
>>};
>
>My first reaction was Hey, this is pretty good, but look what it would
>mean: the rule would have to be that *if* the name following `extern'
>were not defined as a type, which is what would normally appear in
>that position, *then* treat it as a namespace.  Then someone who
>misspelled a type name following `extern' wouldn't find out about it
>until link time, and rather indirectly at that.

Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct
is rendered unambiguous by the `{'.  So this objection is invalid.

-- Scott
Gyro@Reasoning.COM




Author: jimad@microsoft.UUCP (Jim ADCOCK)
Date: 1 May 91 22:04:38 GMT
Raw View
In article <1358@appli.se> niklas@appli.se (Niklas Hallqvist) writes:
>I've thought about this, and come to the same conclusions as Ron.
>Well, how should the "use" syntax look like?  How about:

Again, some simple alternatives to "use" blocks is for programmers to use
references as a short named alternative:

 WRAPPERCLASSNAME::doThis();
 WRAPPERCLASSNAME::doThat();
 WRAPPERCLASSNAME::doTheNextThing();

becomes:

 WRAPPERCLASSNAME const x& = ....;
 x.doThis();
 x.doThat();
 x.doTheNextThing();

which is hardly more onerous than:

 use WRAPPERCLASSNAME
 {
  doThis();
  doThat();
  doTheNextThing();
 }

Another alternative is:

class X : public WRAPPERCLASSNAME
{
public:
 static void doABunchOfStuff()
 {
  doThis();
  doThat();
  doTheNextThing();
 }
}

So, I'd rather see implementors spending their time and effort to make
existing features of the language more efficient, and thereby more
widely used, rather than adding new syntax in order to perform occasional
spot optimizations.




Author: beard@ux5.lbl.gov (Patrick C Beard)
Date: 2 May 91 06:27:19 GMT
Raw View
In article <1991Apr29.174033.29627@alias.com> rae@alias.com (Reid Ellis) writes:
#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 <NIHCL.h>
#};

This syntax was created for specifying language specific linkage for linking
to C, FORTRAN, Pascal, etc.  And currently it requires a set of quotes
around the keyword after extern.  I don't think that the namespace usage
is really in the spirit of linkage specification.

I believe that we have everything we need by allowing nested class declarations
and enumerations within a class.  My only problem so far has been with the
fact that the tag type names from nested enums and classes are visible
in the global namespace.  This has been ammended I believe in compilers
that are based on CFront 2.1.  Correct me if I am wrong.

--
//  Patrick C. Beard, Software Engineer, Berkeley Systems, Inc.
//                    "Heroes of technology."
//   beard@lbl.gov, d0346@applelink.apple.com (ATTN: Patrick)




Author: rae@alias.com (Reid Ellis)
Date: 3 May 91 18:33:28 GMT
Raw View
Reid Ellis (that's me) <rae@alias.com> writes:
|Why don't we simply use a syntax which already evokes this concept --
|using "extern"?
|
|extern NIH {
|#include <NIHCL.h>
|};


Scott Layson Burson <gyro@kestrel.edu> writes:
|someone who
|misspelled a type name following `extern' wouldn't find out about it
|until link time, and rather indirectly at that.

Yeah, oh well.

|Besides, the namespace construct *doesn't* mean that the stuff between
|the braces is `extern'.  So I would still prefer the keyword
|`namespace'.

Well, in a last-ditch attempt to avoid a new keyword :-) how about the
following?

extern default NIH {
#include <NIHCL.h>
};

Someone mentioned also using "default" by itself, comme ca:

default NIH {
#include <NIHCL.h>
};

But the word "default" on its own doesn't imply to me that we're
labelling a namespace.  But then again..  Thoughts?  Who mentioned
this use of "default"?

Whatever is decided, would hope that these things nest.  i.e.,
assuming we use "default" on its own:

 default ABC {
   default XYZ {
     struct foo {
       static int bar;
     };
   };
 };

 int ABC::XYZ::foo::bar = 23;

Of course, unlike everything else, this proposal will require changes
to the linker.  Will this make it less acceptable to the ANSI
committee?  Can anyone think of a way to do this sans linker changes?
I can't.
      Reid
--
Reid Ellis
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]




Author: robertk@lotatg.lotus.com (Robert Krajewski)
Date: 3 May 91 18:57:40 GMT
Raw View
In article <1991May1.192611.20568@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:

   From: gyro@kestrel.edu (Scott Layson Burson)
   Date: 1 May 91 19:26:11 GMT
   Distribution: comp.std.c++
   Organization: Kestrel Institute, Palo Alto, CA

   In article <1991Apr30.202357.13791@kestrel.edu> I wrote:
   >In article <1991Apr29.174033.29627@alias.com> rae@alias.com (Reid Ellis) writes:
   >>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 <NIHCL.h>
   >>};

   ...

   Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct
   is rendered unambiguous by the `{'.  So this objection is invalid.

What about this one ?

#define NIH "C"




Author: krey@ira.uka.de (Andreas Krey)
Date: 6 May 91 08:51:17 GMT
Raw View
In article <ROBERTK.91May3145741@lotatg.lotus.com>, robertk@lotatg.lotus.com (Robert Krajewski) writes:
|> In article <1991May1.192611.20568@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
|>
|>    From: gyro@kestrel.edu (Scott Layson Burson)
|>    >>extern NIH {
|>    >>#include <NIHCL.h>
|>    >>};
|>
|>    ...
|>
|>    Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct
|>    is rendered unambiguous by the `{'.  So this objection is invalid.
|>
|> What about this one ?
|>
|> #define NIH "C"

And, by the way, what about:

#define class struct
#define private public
#define protected public

#include <anyclass.h>

With the cpp you can wreak everything.
And dont name a variable/class 'sun3' if you are on one.
--
Andy




Author: rae@alias.com (Reid Ellis)
Date: 7 May 91 23:04:44 GMT
Raw View
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 <NIHCL.h>
|};

Scott Layson Burson <gyro@kestrel.edu> writes:
|Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct
|is rendered unambiguous by the `{'.  So this objection is invalid.

Robert Krajewski <robertk@lotatg.lotus.com> 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.  It would be like saying

 What about "#define class struct"?

as an objection to the "class" keyword.

      Reid
--
Reid Ellis
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]




Author: robertk@lotatg.lotus.com (Robert Krajewski)
Date: 9 May 91 16:19:00 GMT
Raw View
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 <NIHCL.h>
   |};

   Scott Layson Burson <gyro@kestrel.edu> writes:
   |Oops -- Jerry Schwarz (jss@kpc.com) has corrected me -- the construct
   |is rendered unambiguous by the `{'.  So this objection is invalid.

   Robert Krajewski <robertk@lotatg.lotus.com> 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.




Author: rfg@NCD.COM (Ron Guilmette)
Date: 12 May 91 08:14:22 GMT
Raw View
In article <ROBERTK.91May9121900@lotatg.lotus.com> robertk@lotatg.lotus.com (Robert Krajewski) writes:
>
>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.

I have to agree.  Your reasoning is sound.

I see there as being only two reasonable possibilities for the new keyword.
Rather that using Keith Rowe's "bundle" I would prefer to see this new
feature re-use some keyword which is already in use for this exact purpose
in some other language.  That yields two possibilities, i.e. "module" (which
is used in Modula, Clu, Euclid, and now in Fortran90) and "package" (which
is used in Ada, and Common Lisp).  I suppose that we could also consider
"unit" (which was used in UCSD-Pascal) but that seem too uncommon for me.

Given that Ada is a dirty word in most C++ circles, I think that "module"
is probably the choice which will engender the least hostility.

--

// Ron ("Loose Cannon") Guilmette
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.




Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 19 Apr 91 16:32:53 GMT
Raw View
I seem to recall a recent posting or two discussing the possibility of
controlling the top-level namespace of a C++ program through some sort
of module facility.  Or rather, one person said they thought some such
proposal had been made, and there was a response by someone else who
was not aware of any such proposal.  Or something like that.  (I
didn't see the messages when I quickly scanned back.)  Anyhow --

To see if we can get some discussion going on the matter, let me
sketch a simple proposal.  Suppose we were to introduce a keyword
"module" with a simple syntax:

   module Foo {
     // ... declarations
   }

The intent here is that the declarations within the braces have
exactly the same form as those normally found at top level, so that
one can write things like

   module Foo {
   #include "something.h"
   }

where the author of the header file need not have done anything
special to make such usage possible.

The meaning would be simply to put the code within the braces into
namespace Foo, as if Foo were a class; outside the construct,
referencing names defined inside it would require prepending `Foo::'.
Multiple module constructs with the same name would refer to the same
module, so that one could have a header file that looked like the
previous example and also, separately, a .cc file containing:

   module Foo {
   #include "something.cc"
   }

and the two pieces would connect up in the obvious way.

Seems like this would make the world safe for all those of us who want
to name one of our classes "Object".

The only problem I can see with it concerns the issue of binary-only
library distribution, which, it has already been noted, is problematic
anyway.  It is not hard to imagine linker extensions that could fix
this, but I gather that is considered an undesirable thing to do.

It seems to me that C++ needs something along these lines fairly
badly.  Certainly this strikes me as a far better sort of solution
than any kind of central registry of names.  Comments?

-- Scott
Gyro@Reasoning.COM




Author: cok@islsun.Kodak.COM (David Cok)
Date: 19 Apr 91 18:39:22 GMT
Raw View
In article <1991Apr19.163253.22253@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
>
>To see if we can get some discussion going on the matter, let me
>sketch a simple proposal.  Suppose we were to introduce a keyword
>"module" with a simple syntax:
>
>   module Foo {
>     // ... declarations
>   }
>
>The intent here is that the declarations within the braces have
>exactly the same form as those normally found at top level, so that
>one can write things like
>
>   module Foo {
>   #include "something.h"
>   }
>
>where the author of the header file need not have done anything
>special to make such usage possible.

Would it work just as well to say
class Foo {
#include "something.h"
}

since classes and everything else (?) can -- eventually -- be nested inside
classes.
>
>The only problem I can see with it concerns the issue of binary-only
>library distribution, which, it has already been noted, is problematic
>anyway.  It is not hard to imagine linker extensions that could fix
>this, but I gather that is considered an undesirable thing to do.
>

We already (pre-C++) have namespace problems in libraries.  Two functions
in different libraries can have the same name and the ambiguity is
resolved by the order in which the libraries are linked.  The same thing in
the C++ case will take care of all situations except where the programmer
actually uses a global name which is in both libraries but wants the one from
the library later in the compile command line.  This is likely to be much
more common in C++ than it was in C I think.  The linker extension to
accommodate this would be straightforward.
 1) Be able to associate a scope identifier (e.g. MyLib:: ) with
 a library either in a program or on the command line.
 2) Have the linker defer any references beginning with such scope
 identifiers until the library associated with that scope id.
 3) Global names without scope ids associated with libraries would
 be resolved as before -- giving backwards compatibility.
Still perhaps more than anyone wants to do.  However if anyone ever changes
the linker for other reasons...

David R. Cok
Eastman Kodak Company -- Imaging Science Lab
cok@Kodak.COM




Author: rfg@NCD.COM (Ron Guilmette)
Date: 20 Apr 91 07:48:20 GMT
Raw View
In article <1991Apr19.183922.1982@kodak.kodak.com> cok@islsun.Kodak.COM (David Cok) writes:
>In article <1991Apr19.163253.22253@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
>>
>>To see if we can get some discussion going on the matter, let me
>>sketch a simple proposal.  Suppose we were to introduce a keyword
>>"module" with a simple syntax:
>>
>>   module Foo {
>>     // ... declarations
>>   }
>>
...
>
>Would it work just as well to say
>class Foo {
>#include "something.h"
>}
>
>since classes and everything else (?) can -- eventually -- be nested inside
>classes.

Right.  That's just what I proposed awhile back.  However I think that Scott
wanted something slightly more than this (and so do I).

It is (or will be in future) reasonably easy to package up all of the things
that we now put into include files and give them all their own little
namespaces by wrapping them in `class <identifier> { ... }'.  (Note that
you will have to declare all data member and function member as "static"
if you want the effect of a "module" however.)

The problem is *not* one of establishing new "modules" or new "namespaces"
(which class declarations can do quite well, thank you).  No.  The problem
is that if you do this, it becomes quite cumbersome to *reference* the
things whose declarations you have now nested within class declarations.
Specifically, it is quite irritating to have to write out the extra
CLASSNAME:: qualification all over the place.

How can this problem (i.e. the *real* problem) be solved?

Recently, I proposed the introduction of a Pascal style `with' statement.
Thinking more about it, I now realize that it would probably be better to
have something more like an Ada `use' statement to solve this problem.
An Ada `use' statement looks just like `use <module>;' (where <module>
is just an identifier for some module).  You put such a statement into
any scope where you want to be able to refer to the members of <module>
*without* the qualification.  (The `use' statement only applies within
the scope which contains it.)  If you `use' two or more modules within
the same scope, and if those modules contain identically named declarations
for different things, then in order to refer (unambigously) to any of the
things with the (conflicting) name, you must use the full and explicit
qualification.

The big problem with a Pascal-style `with' statement is that it is treated
as a form of an executable statement (rather like a `while' statement).
Thus, you can't place them at `file-scope' in C++.

But Ada's `use' statement is treated like a declarative statement.  Thus,
if we had such a beast in C++, we could make it legal to write `use'
statements at the file-scope level.  That could be most helpful.

I think that if we had a `use' statement in C++, the problem of namespaces
would be mostly solved.  Of course there would still be that irritating
need to declare data and function members as `static'.  That's where having
a `module <identifier> { ... }' construct would come in handy.  We could
define a `module' to be just like a class except that its data members and
function members would all be *implicitly* static.  Still, I'm sure that
we're all against introducing new keywords if it could be avoided, so how
about just using `class <identifier> static { ... }' rather than requiring
`module <identifier>'.

--

// Ron ("Loose Cannon") Guilmette
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.




Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 21 Apr 91 01:47:46 GMT
Raw View
In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>The problem is *not* one of establishing new "modules" or new "namespaces"
>(which class declarations can do quite well, thank you).

Except that as you point out later on in your message, there is
currently no way to wrap a class declaration around a group of
top-level declarations and have them be treated as static members by
default.  So it seems to me that until some syntax is defined for that
purpose, this is still the primary problem, since as things stand
there's no way to resolve name conflicts at all (without editing the
source, which is exactly what I'm trying to avoid).

>          No.  The problem
>is that if you do this, it becomes quite cumbersome to *reference* the
>things whose declarations you have now nested within class declarations.
>Specifically, it is quite irritating to have to write out the extra
>CLASSNAME:: qualification all over the place.
>
>How can this problem (i.e. the *real* problem) be solved?

Though I'm not opposed to an attempt to solve this problem in some
such way as you suggest, I think you overrate it.  I've worked on a
number of projects where the qualifiers were part of the names (i.e.
the language in use had no namespace facility at all), and therefore
they *always* had to be included, even in references from *inside* the
module.  Even so, it didn't particularly bother me, I guess partly
because the qualifiers made it easy to know what source file to look
in to find a definition.

>Recently, I proposed the introduction of a Pascal style `with' statement.
>Thinking more about it, I now realize that it would probably be better to
>have something more like an Ada `use' statement to solve this problem.

I agree that this would be handy.

>I think that if we had a `use' statement in C++, the problem of namespaces
>would be mostly solved.  Of course there would still be that irritating
>need to declare data and function members as `static'.  That's where having
>a `module <identifier> { ... }' construct would come in handy.  We could
>define a `module' to be just like a class except that its data members and
>function members would all be *implicitly* static.  Still, I'm sure that
>we're all against introducing new keywords if it could be avoided, so how
>about just using `class <identifier> static { ... }' rather than requiring
>`module <identifier>'.

Except it would presumably be `struct <identifier> static { ... }',
since it wouldn't do you much good if all the members were private!

Personally, I would prefer the introduction of a keyword in this case,
because it seems awfully strange to be using `struct' when I'm really
not declaring a structure.  Also, if there were also some sort of
`use' declaration, I think I would really want it to work only on
modules; otherwise its definition has to be that it makes the names of
only static members visible, because it wouldn't make sense to make
the names of normal (nonstatic) members visible, and I think that
would be weird.

-- Scott




Author: horstman@mathcs.sjsu.edu (Cay Horstmann)
Date: 21 Apr 91 15:44:32 GMT
Raw View
In article <1991Apr19.163253.22253@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
>
>To see if we can get some discussion going on the matter, let me
>sketch a simple proposal.  Suppose we were to introduce a keyword
>"module" with a simple syntax:
>
>   module Foo {
>     // ... declarations
>   }
>
>The intent here is that the declarations within the braces have
>exactly the same form as those normally found at top level, so that
>one can write things like
>
>   module Foo {
>   #include "something.h"
>   }
>
>where the author of the header file need not have done anything
>special to make such usage possible.
>
Let me refer to this as the "standard proposal" for no better reason than
that I have proposed the exact same syntax elsewhere.

One could embellish this to give the module private and public parts,
overcoming the wretched "static/extern" syntax.

But there are some significant problems with name space control. While you
now can disambiguate a name conflict in the source file

 module A { ... int f() ... }
 module B { ... int f() ... }

on the link level, there are still two global functions f() which cannot
be distinguished. Sure, the implementation of the f()'s could also be
contained in module A { ... } and module B { ... } wrappers, but that
rather negates the module A { #include "..." } trick. And it doesn't
protect against the problem of two module designers assigning the same
module name.

Also, one may well argue that

 module A { /* global data and functions */ }

is no different from

 class A { /* the same data and functions */ }
 main() { A anInstance; /* ... */ }

so the feature is unnecessary.

Does anyone have any idea how to overcome the problem of two classes/
global functions having the same name using a renaming syntax like in
Eiffel? I can see how this works in the compilation stage, but I still
don't understand how one can do the link step with a standard linker.

Cay




Author: dag@control.lth.se (Dag Bruck)
Date: 21 Apr 91 17:27:35 GMT
Raw View
In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>The problem is *not* one of establishing new "modules" or new "namespaces"
>(which class declarations can do quite well, thank you).  No.  The problem
>is that if you do this, it becomes quite cumbersome to *reference* the
>things whose declarations you have now nested within class declarations.
>Specifically, it is quite irritating to have to write out the extra
>CLASSNAME:: qualification all over the place.

Wouldn't this be a case were multiple inheritance could be used?

 struct Modulename {
  static ....;
  static ....;
 };

 class Foo : private Modulename {
  ....
 };

I think it would solve the problem of "getting into" the module for code
packaged in classes.  Name conflicts only arise when an ambiguous name
is _used_, if I remember correctly, and can be solved with explicit
qualification.

Another property I like in Modula-2 is to be able to selectively
import names from a module, i.e.,

 IMPORT fission FROM Atomic;

I do not see how this very useful feature could be provided with the
class-as-module-and-no-new-keywords-please approach.

  -- Dag Bruck




Author: rfg@NCD.COM (Ron Guilmette)
Date: 21 Apr 91 23:53:21 GMT
Raw View
In article <1991Apr21.014746.3526@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
>In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>>The problem is *not* one of establishing new "modules" or new "namespaces"
>>(which class declarations can do quite well, thank you).
>
>Except that as you point out later on in your message, there is
>currently no way to wrap a class declaration around a group of
>top-level declarations and have them be treated as static members by
>default...
>>          No.  The problem
>>is that if you do this, it becomes quite cumbersome to *reference* the
>>things whose declarations you have now nested within class declarations.
>>Specifically, it is quite irritating to have to write out the extra
>>CLASSNAME:: qualification all over the place.
>>
>>How can this problem (i.e. the *real* problem) be solved?
>
>Though I'm not opposed to an attempt to solve this problem in some
>such way as you suggest, I think you overrate it.

OK.  Perhaps I do.  Let's agree that there are two problems here, namely:

 We need a feature (similar to classes) which will (by default)
 make any data member or function member `static' by default.
 (Note that all sorts of things like typdefs, enum types, struct
 types, union types, class types may now also be `members' of some
 containing class, but staticness/non-staticness is only an issue
 for the data members and function members.)

 We also need a related feature which would "open the scope" of
 such a "module" (within some other scope) so that (within that
 other scope) we don't have to deal with the tedium of writing
 CLASSNAME:: all of the time.

Regarding the latter problem, I wrote:

>>... it would probably be better to
>>have something more like an Ada `use' statement to solve this problem.
>
>I agree that this would be handy.

OK.  One down.  Now... about that first problem... given that we can nest
groups of declarations in `class' declarations...

>>... there would still be that irritating
>>need to declare data and function members as `static'.  That's where having
>>a `module <identifier> { ... }' construct would come in handy.  We could
>>define a `module' to be just like a class except that its data members and
>>function members would all be *implicitly* static.  Still, I'm sure that
>>we're all against introducing new keywords if it could be avoided, so how
>>about just using `class <identifier> static { ... }' rather than requiring
>>`module <identifier>'.

>Personally, I would prefer the introduction of a keyword in this case.

I would prefer it myself, but remember that each tiny change of that sort
causes the x3j16 membership to scream bloody murder.  If we could convince
x3j16 *just* that "default-static" classes and `use' statements were
essential, I would say that we would have done a damn good day's work.
It would be pushing our luck to imagine that we might also be successful
in slipping in a new keyword to boot!

>... Also, if there were also some sort of
>`use' declaration, I think I would really want it to work only on
>modules;...

I disagree.

>...otherwise its definition has to be that it makes the names of
>only static members visible, because it wouldn't make sense to make
>the names of normal (nonstatic) members visible...

I don't see anything wrong with  a generalized "opening of the scope"
which applies to both static and non-static members.  In some cases,
it might actually be useful.  For example:

 struct S {
  int data_member;
  void func_member (void);
 };

 int S::*data_mbr_ptr;
 int S::*func_mbr_ptr;

 int i;

 void example ()
 {
  use S;  // scope opener

  i = S::data_member; // error - no object specified
  i = data_member; // error - no object specified

  S::func_member(); // error - no object specified
  func_member ();  // error - no object specified

  data_mbr_ptr = &S::data_member;  // OK
  data_mbr_ptr = &data_member;  // also OK

  func_mbr_ptr = &S::func_member;  // OK
  func_mbr_ptr = func_member;  // also OK
 }

--

// Ron ("Loose Cannon") Guilmette
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.




Author: niklas@appli.se (Niklas Hallqvist)
Date: 21 Apr 91 13:27:35 GMT
Raw View
rfg@NCD.COM (Ron Guilmette) writes:

:In article <1991Apr19.183922.1982@kodak.kodak.com> cok@islsun.Kodak.COM (David Cok) writes:
:>In article <1991Apr19.163253.22253@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
:>>
:>>To see if we can get some discussion going on the matter, let me
:>>sketch a simple proposal.  Suppose we were to introduce a keyword
:>>"module" with a simple syntax:
:>>
:>>   module Foo {
:>>     // ... declarations
:>>   }
:>>
:...
:>
:>Would it work just as well to say
:>class Foo {
:>#include "something.h"
:>}
:>
:>since classes and everything else (?) can -- eventually -- be nested inside
:>classes.

:Right.  That's just what I proposed awhile back.  However I think that Scott
:wanted something slightly more than this (and so do I).

:It is (or will be in future) reasonably easy to package up all of the things
:that we now put into include files and give them all their own little
:namespaces by wrapping them in `class <identifier> { ... }'.  (Note that
:you will have to declare all data member and function member as "static"
:if you want the effect of a "module" however.)

:The problem is *not* one of establishing new "modules" or new "namespaces"
:(which class declarations can do quite well, thank you).  No.  The problem
:is that if you do this, it becomes quite cumbersome to *reference* the
:things whose declarations you have now nested within class declarations.
:Specifically, it is quite irritating to have to write out the extra
:CLASSNAME:: qualification all over the place.

:How can this problem (i.e. the *real* problem) be solved?

:Recently, I proposed the introduction of a Pascal style `with' statement.
:Thinking more about it, I now realize that it would probably be better to
:have something more like an Ada `use' statement to solve this problem.
:An Ada `use' statement looks just like `use <module>;' (where <module>
:is just an identifier for some module).  You put such a statement into
:any scope where you want to be able to refer to the members of <module>
:*without* the qualification.  (The `use' statement only applies within
:the scope which contains it.)  If you `use' two or more modules within
:the same scope, and if those modules contain identically named declarations
:for different things, then in order to refer (unambigously) to any of the
:things with the (conflicting) name, you must use the full and explicit
:qualification.

:The big problem with a Pascal-style `with' statement is that it is treated
:as a form of an executable statement (rather like a `while' statement).
:Thus, you can't place them at `file-scope' in C++.

:But Ada's `use' statement is treated like a declarative statement.  Thus,
:if we had such a beast in C++, we could make it legal to write `use'
:statements at the file-scope level.  That could be most helpful.

:I think that if we had a `use' statement in C++, the problem of namespaces
:would be mostly solved.  Of course there would still be that irritating
:need to declare data and function members as `static'.  That's where having
:a `module <identifier> { ... }' construct would come in handy.  We could
:define a `module' to be just like a class except that its data members and
:function members would all be *implicitly* static.  Still, I'm sure that
:we're all against introducing new keywords if it could be avoided, so how
:about just using `class <identifier> static { ... }' rather than requiring
:`module <identifier>'.

I've thought about this, and come to the same conclusions as Ron.
Well, how should the "use" syntax look like?  How about:

default class CLASSNAME-LIST {
  // code goes here;
}

This way, we won't need to introduce new keywords.  Possibly the
"class" keyword could be left out but I think it makes the code
more readable.  The effect of such a statement would be to push
the scopes of the specified classes, much like the effect of
entering the scope of a class who publicly inherits from those
classes.  The last point made is relevant to compiler implementors
who could reuse the scope-handling in these cases.  Would anybody
care to comment on this?  Should we (the net) try to write a proposal
to the ANSI commitee before their june meeting in Lund, Sweden (at
least I think that's the case, some of the members will speak at
some seminars there, which I'll try to attend).

    Niklas

--
Niklas Hallqvist Phone: +46-(0)31-40 75 00
Applitron Datasystem Fax:   +46-(0)31-83 39 50
Molndalsvagen 95 Email: niklas@appli.se
S-412 63  GOTEBORG, Sweden     mcsun!sunic!chalmers!appli!niklas




Author: petergo@microsoft.UUCP (Peter GOLDE)
Date: 22 Apr 91 20:50:19 GMT
Raw View
In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>It is (or will be in future) reasonably easy to package up all of the things
>that we now put into include files and give them all their own little
>namespaces by wrapping them in `class <identifier> { ... }'.  (Note that
>you will have to declare all data member and function member as "static"
>if you want the effect of a "module" however.)
>
>The problem is *not* one of establishing new "modules" or new "namespaces"
>(which class declarations can do quite well, thank you).  No.  The problem
>is that if you do this, it becomes quite cumbersome to *reference* the
>things whose declarations you have now nested within class declarations.
>Specifically, it is quite irritating to have to write out the extra
>CLASSNAME:: qualification all over the place.
>
> [proposed 'use' clause to get around this naming problem]

No need to invent new language structures -- use private inheritance.

For example, your class wants to use several libraries.  Each of these
libraries is packaged into a big class, with nested classes for the
real functionality, and maybe a couple of static functions, etc.
I.e., instead of

CARSTUFF.H:
    const int NumTires = 4;
    class Tire {...};
    class Axle {...};
    class Manifold {...};

You do CARSTUFF.H:
    struct CARSTUFF {
      static const int NumTires;
      class Tire {...};
      class Axle {...};
      class Manifold {...};
    };

Now consider what would have been a problem before: you want to
use both the CARSTUFF library, and the TOPOLOGY library, both of which
define (different) Manifold classes.  But you don't want to qualify
the non-conflicting names, like Axle and MetricSpace.
No problem:

class MyClass: private CARSTUFF, private TOPOLOGY
{
    CARSTUFF::Manifold my_auto_manifold;
    TOPOLOGY::Manifold my_topological_manifold;
    HausdorffSpace space;
    Axle axles[2];
};


Peter Golde
petergo%microsoft@uunet.uu.net




Author: jimad@microsoft.UUCP (Jim ADCOCK)
Date: 22 Apr 91 22:35:05 GMT
Raw View
In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
|The problem is *not* one of establishing new "modules" or new "namespaces"
|(which class declarations can do quite well, thank you).  No.  The problem
|is that if you do this, it becomes quite cumbersome to *reference* the
|things whose declarations you have now nested within class declarations.
|Specifically, it is quite irritating to have to write out the extra
|CLASSNAME:: qualification all over the place.
|
|How can this problem (i.e. the *real* problem) be solved?

C++ already has several "solutions" to these kinds of problems:

1) Within a member function "this->" is the default
2) Within a class inherited classnames are the default
3) Using references you can use shorthand names
....

Substituting "module" for "class" in the above list leads to many ideas.
Here's some examples:

// the following silly #defines are introduced just to help show what
// I'm talking about:
#define MODULE class
#define USE :

MODULE XYZCorpClasses
{
public:
 static int intThing;
 class Object { public: void doSomething(); };
 // ....
};

MODULE ABCCorpClasses
{
public:
 class Object { public: void doSomething(); };
 // ....
};

MODULE MyClasses USE public XYZCorpClasses
{
public:
 class Derived : public Object
 { public: void doSomething(); };

 static void main()
 {
  // let's try using some XYZ stuff by default:

  Object object; object.doSomething();
  Derived dirv; dirv.doSomething();

  // now let's use some non-default ABC stuff instead:

  ABCCorpClasses::Object abcOb; abcOb.doSomething();

  // or explicitly use XYZ stuff if we like:

  XYZCorpClasses::Object xyzOb; xyzOb.doSomething();
 }
};


void main() { MyClasses::main(); }




Author: wmm@world.std.com (William M Miller)
Date: 23 Apr 91 03:03:49 GMT
Raw View
dag@control.lth.se (Dag Bruck) writes:
> Another property I like in Modula-2 is to be able to selectively
> import names from a module, i.e.,
>
>         IMPORT fission FROM Atomic;
>
> I do not see how this very useful feature could be provided with the
> class-as-module-and-no-new-keywords-please approach.

This is something I "discovered" recently when Ron Guilmette brought up this
question a while back: You can selectively import types and static members
(data and functions) from a class into a scope using typedefs and
references.  For instance:

        class X {
        public:
           class Y { ... };
           static void f();
           static int i;
           };

        typedef X::Y Y;
        void (&f)() = X::f;
        int& i = X::i;

        void g() {
           Y y;         // X::Y
           f();         // X::f()
           i = 5;       // X::i
           }

It's not as simple as IMPORT x FROM y, but it does the trick.

-- William M. Miller, Glockenspiel, Ltd.
   wmm@world.std.com




Author: robertk@lotatg.lotus.com (Robert Krajewski)
Date: 23 Apr 91 21:39:27 GMT
Raw View
In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:

   Recently, I proposed the introduction of a Pascal style `with' statement.
   Thinking more about it, I now realize that it would probably be better to
   have something more like an Ada `use' statement to solve this problem.
   An Ada `use' statement looks just like `use <module>;' (where <module>
   is just an identifier for some module). ... If you `use' two or
   more modules within
   the same scope, and if those modules contain identically named declarations
   for different things, then in order to refer (unambigously) to any of the
   things with the (conflicting) name, you must use the full and explicit
   qualification.

The Common Lisp package system has a similar scheme; in fact, there
is a function called USE-PACKAGE which does (effectively) what ADA use
does, except that the CL package system is really something that works
at READ (parse) time on symbols, not at compile time on semantic
units.

I'm not sure if ``overloading'' class is a good way to introduce such
a feature; adding new keywords would be justified in this case.




Author: gyro@kestrel.edu (Scott Layson Burson)
Date: 24 Apr 91 10:07:33 GMT
Raw View
In article <5176@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>In article <1991Apr21.014746.3526@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes:
>>... Also, if there were also some sort of
>>`use' declaration, I think I would really want it to work only on
>>modules; otherwise its definition has to be that it makes the names of
>>only static members visible, because it wouldn't make sense to make
>>the names of normal (nonstatic) members visible...
>
>I disagree.
>
>I don't see anything wrong with  a generalized "opening of the scope"
>which applies to both static and non-static members.  In some cases,
>it might actually be useful.  For example:
>
> struct S {
>  int data_member;
>  void func_member (void);
> };
>
> int S::*data_mbr_ptr;
> int S::*func_mbr_ptr;
>
> int i;
>
> void example ()
> {
>  use S;  // scope opener
>
>  i = S::data_member; // error - no object specified
>  i = data_member; // error - no object specified
>
>  S::func_member(); // error - no object specified
>  func_member ();  // error - no object specified
>
>  data_mbr_ptr = &S::data_member;  // OK
>  data_mbr_ptr = &data_member;  // also OK
>
>  func_mbr_ptr = &S::func_member;  // OK
>  func_mbr_ptr = func_member;  // also OK
> }

In the language as it stands (the ARM, anyway), the only way to create
a pointer to member is with the `&A::b' syntax.  I vigorously object
to any proposal that would make it possible to create them without the
qualifier, because I think that they are very much unlike pointers
(the term "pointer to member" notwithstanding).

I also think this example is pretty contrived.

I stand by my original opinion: the scope opener makes sense only on
static members.

-- Scott
Gyro@Reasoning.COM




Author: rae@alias.com (Reid Ellis)
Date: 25 Apr 91 06:07:21 GMT
Raw View
Scott Layson Burson <gyro@kestrel.edu> writes:
|Suppose we were to introduce a keyword "module" with a simple syntax:
|   module Foo {
|     // ... declarations
|   }

Ron Guilmette <rfg@NCD.COM> writes:
|how about just using `class <identifier> static { ... }' rather than
|requiring `module <identifier>'?

Niklas Hallqvist <niklas@appli.se> writes:
|How about:
|
|default class CLASSNAME-LIST {
|  // code goes here;
|}

I'd like something similar to Ron's idea, but the other way around:

static class <identifier> {
 // ...
}

Did you know that the above currently passes cfront without a peep?
The "static" doesn't actually *do* anything, but nothing complains.
This could be more generally defined as any storage-specifier
preceding a class definition becomes the default storage-specification
for the scope of the class?  Should it include [previously[ automatic
variables inside [non-inline] method definitions?  Hrm.  Perhaps only
limited to the scope of the class definition..

     Reid
--
Reid Ellis     1 Trefan Street Apt. E, Toronto ON, M5A 3A9
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]




Author: raeburn@athena.mit.edu (Ken Raeburn)
Date: 26 Apr 91 20:57:43 GMT
Raw View
In article <1991Apr25.060721.12694@alias.com> rae@alias.com (Reid Ellis) writes:

   Scott Layson Burson <gyro@kestrel.edu> writes:
   |Suppose we were to introduce a keyword "module" with a simple syntax:
   |   module Foo {
   |     // ... declarations
   |   }

   Ron Guilmette <rfg@NCD.COM> writes:
   |how about just using `class <identifier> static { ... }' rather than
   |requiring `module <identifier>'?

   Niklas Hallqvist <niklas@appli.se> writes:
   |How about:
   |
   |default class CLASSNAME-LIST {
   |  // code goes here;
   |}

   I'd like something similar to Ron's idea, but the other way around:

   static class <identifier> {
    // ...
   }

   Did you know that the above currently passes cfront without a peep?
   The "static" doesn't actually *do* anything, but nothing complains.

This is probably because
 static class X { ... } x;
would be a valid declaration.  It wouldn't be unreasonable for the
translator to complain about storage-class specifiers used in empty
declarations, but I wouldn't expect it.

   This could be more generally defined as any storage-specifier
   preceding a class definition becomes the default storage-specification
   for the scope of the class?

You could only do it for otherwise-empty declarations, and then the
result depends on whether an identifier name follows the class body.
Bletch.

Ron's suggestion works best of those above, in my opinion, because the
construct (specifically the placement of "static") bears little
resemblance to existing constructs.  The one Niklas proposes, if (as
he suggested) the "class" keyword becomes optional, might confuse a
compiler trying to do error recovery (e.g., from a missing ":" after
"default").

I haven't thought about it enough to know which suggestions I like as
a user of the language.  I've spent plenty of time recently dealing
with the g++ grammar, though.




Author: rfg@NCD.COM (Ron Guilmette)
Date: 27 Apr 91 00:35:26 GMT
Raw View
Withe regard to the `module {}' discussion...

In article <1991Apr21.172735.1123@lth.se> dag@control.lth.se (Dag Bruck) writes:
>In article <5143@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>>... { one problem with modules is } ...
>>... it is quite irritating to have to write out the extra
>>CLASSNAME:: qualification all over the place.
>
>Wouldn't this be a case were multiple inheritance could be used?
>
...
> class Foo : private Modulename { ... };
>
>I think it would solve the problem of "getting into" the module for code
>packaged in classes.

I agree, but that's *not* a good enough general solution.  I want to be
able to use the stuff which is encased in a "module" even when I'm not
in some class (or class member function).

>Another property I like in Modula-2 is to be able to selectively
>import names from a module, i.e.,
>
> IMPORT fission FROM Atomic;

Language designers have gone back and forth on this issue over time.

In some languages, you can EXPORT everything from a module.
In some languages you can EXPORT a just an explicit list of names from a module.
In some langauges you can IMPORT everything from a module.
In some languages you can IMPORT a just an explicit list of names from a module.


Of all these possibilities, I like the way that Ada and C++ both seem to
handle things.  Specifically:

 In Ada (and C++) you don't have to say anything special to
 export names from a package (or a class in the case of C++).
 Neither do you have to say anything explicit in order to get at
 (i.e. "import") the names from that package (class) into any
 scope where the package (class) itself is visible.

 In both languages you do however have some control over what does
 and does not get exported from a package (class).  You exercise
 this control by breaking up the package (class) into public and
 private parts.  That is a sufficient degree of control to satisfy
 me (if not others).

--

// Ron ("Loose Cannon") Guilmette
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.




Author: rfg@NCD.COM (Ron Guilmette)
Date: 27 Apr 91 01:41:06 GMT
Raw View
In article <1358@appli.se> niklas@appli.se (Niklas Hallqvist) writes:
>rfg@NCD.COM (Ron Guilmette) writes:
>
>:In article <1991Apr19.183922.1982@kodak.kodak.com> cok@islsun.Kodak.COM (David Cok) writes:
>
>I've thought about this, and come to the same conclusions as Ron.
>Well, how should the "use" syntax look like?  How about:
>
>default class CLASSNAME-LIST {
>  // code goes here;
>}
>
>This way, we won't need to introduce new keywords.  Possibly the
>"class" keyword could be left out but I think it makes the code
>more readable...

>... Should we (the net) try to write a proposal
>to the ANSI commitee before their june meeting in Lund, Sweden (at
>least I think that's the case, some of the members will speak at
>some seminars there, which I'll try to attend).

Sure.  Why not?  I think that the x3j16 committee (and especially the
libraries working group) would  probably thank us for it.

Let me see if I can get the ball rolling a bit (and see where it goes).

First off, I must say that I think that the proposal should be entirely
non-committal about the specific syntax and keywords used.  We know what
our *real* goal is right?  We want a specific *feature*.  None of us
is going to die if the keywords which must be used to code an instance
of that feature are something other than what we would prefer.  I think
that most of us can manage to adapt to whatever keywords x3j16 likes
best, as long as we get the *feature*.  Arguing for a specific keyword
(or set of keywords) is only likely to turn-off some members of x3j16,
so why not just propose the feature and ask x3j16 to decide what keywords
they want to use to express it?

Here are some of the possibilities:

  module <identifier> { ... };
  package <identifier> { ... };
  default class <identifier> { ... };
  class <identifier> static { ... };

Let's not argue about that.  Let's just pick some convenient "stand-in"
for the syntax/keywords (just for now) and let argue instead about the
important rules that should apply to this general "feature".

For the sake of example (only) I'll use a (hypothetical) new keyword, i.e.
"package" and I'll assume that the real choice will be left to x3j16.

Now.  What are the rules applicable to this feature?

Well, I can think of a few right away:

 The name of a "package" is (in general) treated like a class name,
 except that you are not allowed to declared objects of a "package"...
 i.e. the following is illegal:

  package foobar { ... } object;

 as is:

  package foobar { ... };
  foobar object;

 You are not allowed to take the address of a "package".  (That's
 only logical, since the only name that you have for it acts
 mostly like a class name anyway, and it's likewise nonsensical
 to take the address of a class name.)  Also, there are no pointers
 to packages, references to packages, or pointers to members of
 packages.

 All data and function members of a "package" are implicitly "static".
 They may also be *explicitly* declared to be "static", but in such
 cases, there must be a definition of the given member somewhere
 (later) within the same compilation unit, and these definitions
 will be given "static linkage" by the compiler.

 Function members of packages may never be declared to be virtual.

 Since there are no references to packages (and since they would
 nonsensical anyway) packages DO NOT automatically have copy
 constructors or assignment operators implicitly generated for
 them (by the compiler).  (Each package does however get a default
 constructor generated automatically for it by the compiler if one
 is not explicitly provided.)

 A package may have a constructor and a destructor.  If provided, the
 constructor and destructor act just like static member functions
 (i.e. they have no `this' pointer).  If provided, a package
 constructor must take no arguments, and this constructor will be
 automatically invoked once (before main() is entered).  It is
 never invoked otherwise (not even during the construction of an
 object of some class type whose type inherits from the package).
 If provided, a package destructor is invoked once (after main()
 is exited).  It is never invoked otherwise (not even during the
 destruction of an object of some class type whose type inherits
 from the package).

 In all other respects, "packages" act like classes.  In particular,
 package declarations may be nested within functions, within class
 declarations, or within other package declarations.  Likewise,
 classes, packages, and function declarations and definitions
 may be nested within packages.  Furthermore, packages are treated
 just like classes when it comes to inheritance.  You can inherit
 from a package and a package can itself inherit (from either a class
 or from another package).  The "public", "private" and "protected"
 specifiers have all of the same meanings for packages as they do
 for classes.

 Since data and function members of packages are always static,
 taking the address of a member of a package yields a pointer
 to an object or a pointer to a function (respectively) just as
 would be the case for static members of class types.

Did I miss anything?

Oh yes... separately (by attached to this same proposal) there must ultimately
be a description of the proposed "use" statement (if people agree that such
a thing would be needed in case we got "packages").

I don't have time to write that up today, though.

--

// Ron ("Loose Cannon") Guilmette
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.




Author: rae@alias.com (Reid Ellis)
Date: 27 Apr 91 06:18:25 GMT
Raw View
Reid Ellis <rae@alias.com> [that's me] writes:
>I'd like something similar to Ron's idea, but the other way around:
>
>static class <identifier> {
> // ...
>}

As several people pointed out in email, this is used for declarations
like

static class foo { ... } varname;

to declare 'varname' as a static variable.

Never mind... :)
       Reid
--
Reid Ellis     1 Trefan Street Apt. E, Toronto ON, M5A 3A9
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]




Author: niklas@appli.se (Niklas Hallqvist)
Date: 27 Apr 91 04:20:43 GMT
Raw View
rae@alias.com (Reid Ellis) writes:

>Scott Layson Burson <gyro@kestrel.edu> writes:
>|Suppose we were to introduce a keyword "module" with a simple syntax:
>|   module Foo {
>|     // ... declarations
>|   }

>Ron Guilmette <rfg@NCD.COM> writes:
>|how about just using `class <identifier> static { ... }' rather than
>|requiring `module <identifier>'?

>Niklas Hallqvist <niklas@appli.se> writes:
>|How about:
>|
>|default class CLASSNAME-LIST {
>|  // code goes here;
>|}

>I'd like something similar to Ron's idea, but the other way around:

>static class <identifier> {
> // ...
>}

Aha, you misunderstood me...
My syntax wasn't invented for the declaration of a "module",
but rather as a replacement for the Ada "use"-statement.  I like
Ron's original syntax for the declaration, your syntax has the problem
of misunderstanding the definition:

static class X {
  // ...
} foo;

which defines "foo" to be a static instance of X with file scope.  In your proposal X would be an instance of a "module" X with global scope.  Please,
look at this example to understand my thoughts:

class PersistantObjectSystem static {
  class Storable {
    // ...
  }
  Storable* fetch():
}

void foo()
{
  default class PersistantObjectSystem {
    Storable *x = fetch(); // Means:
    // PersistantObjectSystem::Storable *x = Persistant::fetch();

  }
}
void foo (@x());
--
Niklas Hallqvist Phone: +46-(0)31-40 75 00
Applitron Datasystem Fax:   +46-(0)31-83 39 50
Molndalsvagen 95 Email: niklas@appli.se
S-412 63  GOTEBORG, Sweden     mcsun!sunic!chalmers!appli!niklas




Author: shankar@hpcupt3.cup.hp.com (Shankar Unni)
Date: 27 May 91 04:58:02 GMT
Raw View
In comp.std.c++, rfg@NCD.COM (Ron "Loose Cannon" :-] Guilmette) writes:

> Given that Ada is a dirty word in most C++ circles, I think that "module"
> is probably the choice which will engender the least hostility.

An even more subjective criterion, but which, IMHO, should also be seriously
considered, is the likelihood of a proposed keyword being used as an identifier
in someone's C (or C++) program. One of the worst new keywords in C++ was
"class", which broke a heck of a lot of old C programs (not to mention the X11
headers). Still, that's water under the bridge. Let's, however, try to avoid
repeating the mistake.

"module" *seems* less likely to be used as an id than "package", but what do
I know?
-----
Shankar Unni                                   E-Mail:
HP India Software Operation, Bangalore       Internet: shankar@india.hp.com
Phone : +91-812-261254 x417                      UUCP: ...!hplabs!hpda!shankar