June 06, 2004
On Sun, 06 Jun 2004 21:12:34 +0200, Ivan Senji wrote:

> "DemmeGod" <me@demmegod.com> wrote in message news:pan.2004.06.06.18.40.21.36370@demmegod.com...
>> I don't like this idea.  This basically says that friends can either have no access or full access to my privates, but not limited access. It's not
> 
> this is how it works in C++ (if i understand it correctly) class A
> {}
> class B{friend class A;}
> 
> now A is a friend to B and has unlimited acces to B's members.
> 

I don't like the way C++ does it, then.  However, I do like the way java does it's package-level access: it's got a package keyword that allows package access to that member.  It's simple, and it works well.
June 06, 2004
> file pkg/foo.d:
> private module pkg.foo;
> private int a;  // only visible in foo.d
> int a2;         // visible in foo.d and bar.d but not outside pkg
> 
> file pkg/bar.d:
> module pkg.bar;
> private int b;  // visible in bar.d and foo.d but not outside pkg
> int b2;         // visible anywhere

One drawback of that particular proposal is that it probably would end up
forcing files to be created when they shouldn't be.
Why? Private functions are mostly used as helper functions for public ones.
So if I have a public function I can only have package-level helpers and if
I want a module-level helper it can only be a helper for a package-level
function. That seems like too strong a restriction. I can imagine wanting
module-level helpers (or even class-level but I'm not going there) for
public functions and with this proposal it wouldn't work.
Basically when you look at existing code there aren't all that many
candidates for "private modules" as proposed above.

-Ben


June 06, 2004
Charlie wrote:

> Im an avid supporter of writing as little code as possible to get the job done (
> less time to develop, fewer bugs ) and this to me looks far too verbose.
> 
> I like the idea of 'package level privacy' , but i think 
> 
> 
>>but the compiler annoyingly rejects that. Sorry dude - can't have a directory
>>with the same name and in the same directory as a .d file
> 
> 
> needs to be fixed.  I am alone in thinking the bugs need to be fixed before we
> start adding more features ?

This might not change any time soon.

DemmeGod has already posted this as a bug:
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/168

Walter insists this won't work:
"Having the same name for both a package and a module just isn't going to work - sorry."
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/276

My suspicion is something fundamental about the compiler or liker prohibits this (but it's just a guess).

Perhaps we can work around this limitation with a simple convention:

instead of: module etc.bigint;
use: module etc.bigint.main;

I think something like that could work pretty well. (But I understand that's not as elegant as using the same name for a module and a package.)

Just a suggestion...

-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/
June 06, 2004
In article <pan.2004.06.06.20.13.01.636964@demmegod.com>, DemmeGod says...

>I don't like the way C++ does it, then.  However, I do like the way java does it's package-level access: it's got a package keyword that allows package access to that member.  It's simple, and it works well.

Please could you tell me how Java DEFINES a package. It's been a while since I wrote in Java and I've forgotten. If memory serves correct (and it may not) there isn't necessarily a 1-1 corresponce between packages and directories. Thanks.


Maybe other people organize things differently from me. I like a nice clean heirarchy, with everything in the "right" place. The way I see it, a package must be a tree, not a flat dir, and so packages (by this definition) would contain other packages (as directories contain other directories). If you want to make something in one file visible outside that file, you need a way to specify where (how far up the tree) that visibility stops. If it's visible all the way up to "." then its public!

To be honest, I don't care what keywords we use to express this. I'd be happy with more or less any syntex that did the job.

It just strikes me that, in general, the package "a.b.c.d" should include the package "a.b.c.d.e.f".

For instance, I might want "a.b.c.d.e1.f1.MyClass" to be visible in "a.b.c.d.e2.f2", but not in "a.b.c.d2...", so the visiblity of MyClass needs to "a.b.c.d" and everything therebelow. Ideally, I'd want a way of expressing that somehow within the declaration of MyClass. My suggestion:

In file a.b.c.d.e.f:
>       package(a.b.c.d) MyClass

expresses this very nicely. I'm not hung up on the specific syntax, just on being able to do it. This would be a very nice language feature.

Arcane Jill


June 06, 2004
"Ben Hinkle" <bhinkle4@juno.com> wrote in message news:c9vtrv$2kr$1@digitaldaemon.com...
>
> > file pkg/foo.d:
> > private module pkg.foo;
> > private int a;  // only visible in foo.d
> > int a2;         // visible in foo.d and bar.d but not outside pkg
> >
> > file pkg/bar.d:
> > module pkg.bar;
> > private int b;  // visible in bar.d and foo.d but not outside pkg
> > int b2;         // visible anywhere
>
> One drawback of that particular proposal is that it probably would end up
> forcing files to be created when they shouldn't be.
> Why? Private functions are mostly used as helper functions for public
ones.
> So if I have a public function I can only have package-level helpers and
if
> I want a module-level helper it can only be a helper for a package-level function. That seems like too strong a restriction. I can imagine wanting

Good point, maybe then in case of private module, public should still mean visible outside of the package, and have protected to mean "protected" that is visible in the package but not outside of it.

There are isues to solve, but i have a feeling that it could be done similar to this.

> module-level helpers (or even class-level but I'm not going there) for
> public functions and with this proposal it wouldn't work.
> Basically when you look at existing code there aren't all that many
> candidates for "private modules" as proposed above.

I agree, then Walters plan for package-level friend access would be what i could live with, but there were people who where against unrestricted package level-access.

> -Ben
>
>


June 06, 2004
In article <ca00li$6i9$1@digitaldaemon.com>, J C Calvarese says...
>
>>>but the compiler annoyingly rejects that. Sorry dude - can't have a directory with the same name and in the same directory as a .d file
>
>My suspicion is something fundamental about the compiler or linker prohibits this (but it's just a guess).

I can actually see the problem. But it don't see why it can't be worked around.

Here's the problem: Suppose you have a FILE called abc/def/ghi.d. Suppose you also have a DIRECTORY called abc/def/ghi. Now suppose that within the directory ghi you had a file called abc/def/ghi/jkl.d In this scenario:

>       import abc.def.ghi.jkl;

will read the file jkl.d, because "abc.def.ghi.jkl" refers to the module.

On the other hand, suppose that within the file abc/def/ghi.d you declared:

>       public int jkl;

Now, "abc.def.ghi.jkl" refers to a variable. Compiler freaks out.


But what I /don't/ understand is why the compiler can't just reject such ambiguities as compile-errors. It seems to me that the compiler is rejecting it before the event, JUST IN CASE there might be an ambiguity later on. I don't get it.



>Perhaps we can work around this limitation with a simple convention:
>
>instead of: module etc.bigint;
>use: module etc.bigint.main;
>
>I think something like that could work pretty well. (But I understand that's not as elegant as using the same name for a module and a package.)

The trouble with conventions is that unless Walter puts them in the style guide *AND* has Phobos obey them, there's little chance that the rest of the world will go along with them.

I used the "convention" that submodules all went in "etc.bigint_files". Similarly, in my new project, the main import will be "etc.random", with supporting files somewhere underneath "etc.random_files". I wanted the "normal" import to have a nice short name. But that solution is still not particularly elegant.


Now, apparently, Walter has said:
> Having the same name for both a package and a module
> just isn't going to work - sorry.

Walter, I don't suppose you could tell us why? What have I missed? Maybe we could brainstorm and help you find a way round the problem, whatever it is? And even if we can't, it would be nice to understand why it can't be done.

Cheers,
Jill


June 06, 2004
To tell you the truth, I don't know whether or not package level access in Java allows sub-packages access, as I've never had to use it.

Java, however, does look for the class files in directories == packages. Ex if you're importing a.b.c, it'll look for c.class in the directory a/b. However, it does not require that the source be organized the same way.  I always do, however.

I think we agree that package level access should allow sub-package access. Ex:

module my.a.b;
class c
{
 package int d;
}

----------
module my.a.b.f;
c C = new c;
C.d = 6; //Should work

---------
module my.e;
c C = new c;
C.d = 6; //Should _not_ compile

I don't see any reason for anything more complicated than just that package keyword.  If anything in module e has to access anything in package my.a, the hierarchy has probably been set up poorly.  Do we agree on all of this?

John

On Sun, 06 Jun 2004 21:01:03 +0000, Arcane Jill wrote:

> In article <pan.2004.06.06.20.13.01.636964@demmegod.com>, DemmeGod says...
> 
>>I don't like the way C++ does it, then.  However, I do like the way java does it's package-level access: it's got a package keyword that allows package access to that member.  It's simple, and it works well.
> 
> Please could you tell me how Java DEFINES a package. It's been a while since I wrote in Java and I've forgotten. If memory serves correct (and it may not) there isn't necessarily a 1-1 corresponce between packages and directories. Thanks.
> 
> 
> Maybe other people organize things differently from me. I like a nice clean heirarchy, with everything in the "right" place. The way I see it, a package must be a tree, not a flat dir, and so packages (by this definition) would contain other packages (as directories contain other directories). If you want to make something in one file visible outside that file, you need a way to specify where (how far up the tree) that visibility stops. If it's visible all the way up to "." then its public!
> 
> To be honest, I don't care what keywords we use to express this. I'd be happy with more or less any syntex that did the job.
> 
> It just strikes me that, in general, the package "a.b.c.d" should include the package "a.b.c.d.e.f".
> 
> For instance, I might want "a.b.c.d.e1.f1.MyClass" to be visible in "a.b.c.d.e2.f2", but not in "a.b.c.d2...", so the visiblity of MyClass needs to "a.b.c.d" and everything therebelow. Ideally, I'd want a way of expressing that somehow within the declaration of MyClass. My suggestion:
> 
> In file a.b.c.d.e.f:
>>       package(a.b.c.d) MyClass
> 
> expresses this very nicely. I'm not hung up on the specific syntax, just on being able to do it. This would be a very nice language feature.
> 
> Arcane Jill

June 06, 2004
Another approach would be to change the definition of a compilation unit from a module to a package. The compiler becomes a package-compiler, and a package is the sources it is invoked with. The benefit will be that the compiler knows that it has the complete package, and nothing else. It will then be better able to perform optimizations within the package; ie. remove calls through vtables, perform dead code removal etc.

It can be argued that package membership should be reflected in the source files. That can be done too.

"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:c9vkin$2n9q$1@digitaldaemon.com...
> I definitely endorse the call for package level access, but the question
"what
> is a package?" needs clarification before that can happen. Now, I know
that
> "package" is defined as "directory" in the docs, but when we ask for package-level access, I don't think we are exactly asking for
directory-level
> access. I certainly am not. Let me show you what I mean.
>
> My directory structure is currently as follows:
>
> etc\random.d
> etc\random_files\*.d
> etc\random_files\entropy\*.d
> etc\random_files\prbg\*d
>
> (As I've mentioned before I would prefer that I was allowed to have:
>
> etc\random.d
> etc\random\*.d
> etc\random\entropy\*.d
> etc\random\prbg\*d
>
> but the compiler annoyingly rejects that. Sorry dude - can't have a
directory
> with the same name and in the same directory as a .d file, no way. I hope
this
> is fixed, one day, but it's only an annoyance, not a show-stopper, so I
guess I
> can live with it for now).
>
> Anyway, the point is that, as I far as I am concerned, this entire
heirarchy is
> all part of the same package. For example,
"etc.random_files.entropy.noise" and
> "etc.random_files.prbg.forward_secure" are *friends*, and need access to
each
> other's "package level" functions.
>
> And so I have a suggestion as to how this might work.
>
> SUGGESTION 1:
>
> The suggestion is that we define which package a module is in, right at
the
> start of the file. Like this:
>
> -----------------------------------------------
> >       module etc.random_files.entropy.noise;
> >       package etc.random_files;
> >       import whatever;
>
> -----------------------------------------------
> >       module etc.random_files.entropy.noise;
> >       package etc.random_files;
> >       import whatever;
>
> It would be a compile error if the package name were not an ancestor of
the
> module name.
>
> Now, with this system in force, I could then declare:
>
> >       package class MyClass
> >       {
> >       }
>
> and have that class visible everywhere within my directory tree, but
visible
> nowhere else.
>
> This suggestion mandates that a module can be in precisely one package and
no
> other, which may not be suitable for all situations, so I also have a
second
> suggestion (mutually contradictory with the first) which may be better for
some
> people.
>
> SUGGESTION 2:
>
> Instead of putting a package directive at the top of the file, we specify
it
> instead in the declaration, like this:
>
> >       package(etc.random_files) class MyClass
> >       {
> >       }
>
> Bingo! I've just declared that MyClass is visible anywhere in the
directory
> structure at or below etc.random_files, and nowhere else.
>
> Personally, I think that suggestion 2 is better than suggestion 1,
although
> suggestion 2 makes for cleaner source code.
>
> Arcane Jill
>
>


June 07, 2004
Arcane Jill wrote:

> In article <pan.2004.06.06.20.13.01.636964@demmegod.com>, DemmeGod says...
> 
> 
>>I don't like the way C++ does it, then.  However, I do like the way java
>>does it's package-level access: it's got a package keyword that allows
>>package access to that member.  It's simple, and it works well.
> 
> 
> Please could you tell me how Java DEFINES a package. It's been a while since I
> wrote in Java and I've forgotten. If memory serves correct (and it may not)
> there isn't necessarily a 1-1 corresponce between packages and directories.
> Thanks.
The actual language spec says packages are just names, there is no superpackages/subpackage relationship. I don't think this is optimal, but i'm not sure if a tree of nested namespaces are the best either (foo.bar.module and foo.baz.module can't access each other's package members?)
As far as the standard implementation goes (the spec doesn't even mandate storing the classes on a filesystem!), you have a classpath variable that's a list of directories and zip/jar archives, by default containing the CWD, rt.jar (runtime) and maybe a few others.
Classes in the default package (when you don't specify a package name) are looked for in the root of each item in the classpath, classes in foo.bar would be looked for in /foo/bar/ of each item, and so on.
Sam
June 07, 2004
Arcane Jill wrote:
> In article <ca00li$6i9$1@digitaldaemon.com>, J C Calvarese says...
> 
>>>>but the compiler annoyingly rejects that. Sorry dude - can't have a directory
>>>>with the same name and in the same directory as a .d file
>>
>>My suspicion is something fundamental about the compiler or linker prohibits this (but it's just a guess).
> 
> 
> I can actually see the problem. But it don't see why it can't be worked around.
> 
> Here's the problem: Suppose you have a FILE called abc/def/ghi.d. Suppose you
> also have a DIRECTORY called abc/def/ghi. Now suppose that within the directory
> ghi you had a file called abc/def/ghi/jkl.d In this scenario:
> 
> 
>>      import abc.def.ghi.jkl;
> 
> 
> will read the file jkl.d, because "abc.def.ghi.jkl" refers to the module.
> 
> On the other hand, suppose that within the file abc/def/ghi.d you declared:
> 
> 
>>      public int jkl;
> 
> 
> Now, "abc.def.ghi.jkl" refers to a variable. Compiler freaks out.
> 
> 
> But what I /don't/ understand is why the compiler can't just reject such
> ambiguities as compile-errors. It seems to me that the compiler is rejecting it
> before the event, JUST IN CASE there might be an ambiguity later on. I don't get
> it.

Thanks for explaining. That could be the problem.

That gave me an idea of another possible problem:

module a;
enum b { item1, item2 }


module a.b;
const int item1 = 99;
const int item2 = 100;


module c;
import a;
import a.b;
void main()
{
    printf("%d\t%d\n", item1, item2);

    /* which items would be printed */
}


But, as with your example, I would expect that the compiler could detect  the ambiguous situation and print an error message. (I still wonder if a more serious problem exists behind the scenes.)


>>Perhaps we can work around this limitation with a simple convention:
>>
>>instead of: module etc.bigint;
>>use: module etc.bigint.main;
>>
>>I think something like that could work pretty well. (But I understand that's not as elegant as using the same name for a module and a package.)
> 
> 
> The trouble with conventions is that unless Walter puts them in the style guide
> *AND* has Phobos obey them, there's little chance that the rest of the world
> will go along with them.

I've found that if enough people demand a change, Walter can be persuaded to address an issue. Especially if there's a consensus on what the precise problem is.


> I used the "convention" that submodules all went in "etc.bigint_files".
> Similarly, in my new project, the main import will be "etc.random", with
> supporting files somewhere underneath "etc.random_files". I wanted the "normal"
> import to have a nice short name. But that solution is still not particularly
> elegant.

Have you considered a shorter directory name? (I'll throw out some unsolicited suggestions.)

_bigint
bigint_
bigint_mod (module)
bigint_pkg (package)


> 
> Now, apparently, Walter has said:
> 
>>Having the same name for both a package and a module
>>just isn't going to work - sorry.
> 
> 
> Walter, I don't suppose you could tell us why? What have I missed? Maybe we
> could brainstorm and help you find a way round the problem, whatever it is? And
> even if we can't, it would be nice to understand why it can't be done.
> 
> Cheers,
> Jill
> 
> 


-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/