www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Private declaration in module not private

reply "Garett Bass" <garettbass studiotekne.com> writes:
Is it possible to protect a class or function at module-scope with the private
attribute?  It would be handy to hide helper classes 
and functions within modules.  I tried declaring a private class and a bunch of
functions in a private scope block, but they remain 
accessible to other modules when I compile with DMD 0.137.

Regards,
Garett 
Nov 04 2005
next sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Garett Bass wrote:
 Is it possible to protect a class or function at module-scope with the private
attribute?  It would be handy to hide helper classes 
 and functions within modules.  I tried declaring a private class and a bunch
of functions in a private scope block, but they remain 
 accessible to other modules when I compile with DMD 0.137.
 
 Regards,
 Garett 
 
 

I'd love to hear Walter's opinion on this.
Nov 04 2005
prev sibling next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Garett Bass" <garettbass studiotekne.com> wrote in message 
news:dkhiud$lt5$1 digitaldaemon.com...
 Is it possible to protect a class or function at module-scope with the 
 private attribute?  It would be handy to hide helper classes and functions 
 within modules.  I tried declaring a private class and a bunch of 
 functions in a private scope block, but they remain accessible to other 
 modules when I compile with DMD 0.137.

I think the whole protection attribute system needs to be looked at and made right. Another interesting thing with protection attributes - outer classes can't access provate/protected inner class members, even though they're (obviously) in the same module. I've run into this wall too many times. That, and I can never seem to get package to work right.
Nov 04 2005
prev sibling next sibling parent Dave <Dave_member pathlink.com> writes:
In article <dkhiud$lt5$1 digitaldaemon.com>, Garett Bass says...
Is it possible to protect a class or function at module-scope with the private
attribute?  It would be handy to hide helper classes 
and functions within modules.  I tried declaring a private class and a bunch of
functions in a private scope block, but they remain 
accessible to other modules when I compile with DMD 0.137.

'... accessible to other modules'? Can you post an example? It sounds like you may be speaking of two different things - 'private' declarations are intended to be private to a module, which seems to be the issue you are talking about at first, but it sounds like things are broken in your last sentence. Or, are you talking about making a class definition private: file1.d: private class C { int i = 10; } private { int _i; int foo() { return 10; } } private: C _c; file2.d: import file1; void main() { C c = new C; // Ok printf("%d\n",c.i); // Ok int i = foo(); // should be an error _i = 10; // should be an error _c = new C; // should be an error } Making a class definition (as opposed to a declaration) 'private' is undefined but currently not an error, I think.
Regards,
Garett 

Nov 04 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 5 Nov 2005 00:19:23 -0600, Garett Bass  
<garettbass studiotekne.com> wrote:
 Is it possible to protect a class or function at module-scope with the  
 private attribute?  It would be handy to hide helper classes
 and functions within modules.  I tried declaring a private class and a  
 bunch of functions in a private scope block, but they remain
 accessible to other modules when I compile with DMD 0.137.

You can make the constructor and all static methods private, I believe then no other module will be able to instantiate that class nor call any methods. eg. class Foo { private this() {} private static void bar() {} } Regan
Nov 05 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszrrz4t823k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Sat, 5 Nov 2005 00:19:23 -0600, Garett Bass  
<garettbass studiotekne.com> wrote:
 Is it possible to protect a class or function at module-scope with the  
 private attribute?  It would be handy to hide helper classes
 and functions within modules.  I tried declaring a private class and a  
 bunch of functions in a private scope block, but they remain
 accessible to other modules when I compile with DMD 0.137.

You can make the constructor and all static methods private, I believe then no other module will be able to instantiate that class nor call any methods. eg. class Foo { private this() {} private static void bar() {} }

However, if you could just do: private class Foo { this() {} static void bar() {} } and have the "same" result, that'd be really NICE. I put "same" because with that workaround you are still able to declare references to Foo objects, like: Foo f; // It's ugly even though you can't instantiate a Foo object. Tom
Nov 07 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkhiud$lt5$1 digitaldaemon.com>, Garett Bass says...

[...]

I tried declaring a private class

I agree, private classes don't work for me neither.
and a bunch of functions in a private scope block, but they remain 
accessible to other modules when I compile with DMD 0.137.

With DMD 0.137, when I declare a function inside a private block, it remains private for other modules, at least for my code.
Regards,
Garett 

Tom
Nov 07 2005
parent reply "Garett Bass" <garettbass studiotekne.com> writes:
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising. Regards, Garett
Nov 07 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 7 Nov 2005 17:27:37 -0600, Garett Bass  
<garettbass studiotekne.com> wrote:
 With DMD 0.137, when I declare a function inside a private block, it  
 remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior?

No, I think it's a bug, you should post it to the bugs NG (or I will if you like?) Regan
Nov 07 2005
parent "Garett Bass" <garettbass studiotekne.com> writes:
I will submit the bug.

"Regan Heath" <regan netwin.co.nz> wrote in message
news:opszv9c1j923k2f5 nrage.netwin.co.nz...
 On Mon, 7 Nov 2005 17:27:37 -0600, Garett Bass  <garettbass studiotekne.com>
wrote:
 With DMD 0.137, when I declare a function inside a private block, it  remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior?

No, I think it's a bug, you should post it to the bugs NG (or I will if you like?) Regan

Nov 07 2005
prev sibling next sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO) Regards Tom
Nov 07 2005
parent reply Dave <Dave_member pathlink.com> writes:
In article <dkor1o$1064$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO)

I think it is undef. because I've never seen it mentioned in the docs.
Regards

Tom

Nov 07 2005
next sibling parent "Garett Bass" <garettbass studiotekne.com> writes:
But doesn't it seem reasonable to assume that anything (methods, variables,
classes, structs, templates, whatever else) declared 
private at module scope should be private if anything is?  Anything less would
be uncivilized!

;)

"Dave" <Dave_member pathlink.com> wrote in message
news:dkp55h$1758$1 digitaldaemon.com...
 In article <dkor1o$1064$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO)

I think it is undef. because I've never seen it mentioned in the docs.
Regards

Tom


Nov 07 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkp55h$1758$1 digitaldaemon.com>, Dave says...
In article <dkor1o$1064$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO)

I think it is undef. because I've never seen it mentioned in the docs.

Maybe, though the docs lacks of specificity: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." PRIVATE MODULE MEMBERS ARE EQUIVALENT TO STATIC DECLARATIONS IC C PROGRAMS. This is al little confusing to me. As Garett said, it's natural to think that "private class" would be private to other modules and it doesn't sounds like hard work to implement.
Regards

Tom


Tom
Nov 08 2005
parent reply Dave <Dave_member pathlink.com> writes:
In article <dkq9h0$29gr$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkp55h$1758$1 digitaldaemon.com>, Dave says...
In article <dkor1o$1064$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO)

I think it is undef. because I've never seen it mentioned in the docs.

Maybe, though the docs lacks of specificity: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." PRIVATE MODULE MEMBERS ARE EQUIVALENT TO STATIC DECLARATIONS IC C PROGRAMS. This is al little confusing to me. As Garett said, it's natural to think that "private class" would be private to other modules and it doesn't sounds like hard work to implement.

I'm not disagreeing; it is confusing and should be cleared up either in the docs., with a compiler error or by supporting private class definitions; i.e.: so they are not 'visibile' outside of a module. I think some of the confusion (including my own on occasion) may be because it's easy to overlook the difference between 'definition' and 'declaration' - A definition is not really a 'member' of anything, a declaration is. So, it doesn't neccessarily hold for me that private class MyClass { ... } and private MyClass c; should act the same just because of the 'private' attribute, but I wouldn't be opposed to it either.
Regards

Tom


Tom

Nov 08 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkqocs$2ulq$1 digitaldaemon.com>, Dave says...
In article <dkq9h0$29gr$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkp55h$1758$1 digitaldaemon.com>, Dave says...
In article <dkor1o$1064$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkonud$srl$1 digitaldaemon.com>, Garett Bass says...
 With DMD 0.137, when I declare a function inside a private block, it remains
 private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

It's surely a bug, thanks for posting the code, i can see your point now. foo() gets accessible no matter its private declaration, but only when called specifying the enclosing module. Now, is the private class (still visible) a bug or just undefined behavior? If its undef. behavior, it sucks (IMHO)

I think it is undef. because I've never seen it mentioned in the docs.

Maybe, though the docs lacks of specificity: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." PRIVATE MODULE MEMBERS ARE EQUIVALENT TO STATIC DECLARATIONS IC C PROGRAMS. This is al little confusing to me. As Garett said, it's natural to think that "private class" would be private to other modules and it doesn't sounds like hard work to implement.

I'm not disagreeing; it is confusing and should be cleared up either in the docs., with a compiler error or by supporting private class definitions; i.e.: so they are not 'visibile' outside of a module. I think some of the confusion (including my own on occasion) may be because it's easy to overlook the difference between 'definition' and 'declaration' - A definition is not really a 'member' of anything, a declaration is.

Ok, you're maybe right about that difference but D modules cause very much of that confussion because of its nice scope rules (and it's object-like layout). Besides that, what about this (C++)?: class SomeObj { private: int a; typedef int Integer; public: SomeObj() {} ~SomeObj() {} void some_method() { some_function(a); } }; Is "Integer" not a definition and a private one also (we could say a private member definition)?
So, it doesn't neccessarily hold for me that

private class MyClass { ... }

and

private MyClass c;

should act the same just because of the 'private' attribute, but I wouldn't be
opposed to it either.

Regards

Tom


Tom


Tom
Nov 08 2005
prev sibling parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Garett Bass wrote:
With DMD 0.137, when I declare a function inside a private block, it remains
private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

I think it's wrong. I have a feeling this has very much to do with the problems I've previously had with private imports not being all that private. Now, if only Walter could to a look at this ;)
Nov 08 2005
parent reply Dave <Dave_member pathlink.com> writes:
In article <dkqnr5$2tut$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
Garett Bass wrote:
With DMD 0.137, when I declare a function inside a private block, it remains
private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

I think it's wrong. I have a feeling this has very much to do with the problems I've previously had with private imports not being all that private. Now, if only Walter could to a look at this ;)

I do too: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." Looks like a compiler bug to me... Garret, do you want to post to bugs, or should I? - Dave
Nov 08 2005
next sibling parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Dave wrote:
 In article <dkqnr5$2tut$1 digitaldaemon.com>,
 =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
 
Garett Bass wrote:

With DMD 0.137, when I declare a function inside a private block, it remains
private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

I think it's wrong. I have a feeling this has very much to do with the problems I've previously had with private imports not being all that private. Now, if only Walter could to a look at this ;)

I do too: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." Looks like a compiler bug to me...

Here is a yet another simple test case: ====>test.cpp: #include <stdio.h> class m { private: static const int a = 5; }; int main() { printf("%d", m::a); return 0; } ====>test.java: class m { private static int a = 5; } public class m2 { public static void main(String[] p) { System.out.println(m.a); } } ====>test.d: class m { private static int a = 5; } void main() { printf("%d",m.a); } --- test.cpp and test.java won't compile. They complain about the private keyword. test.d compiles nicely even with class m being a private class in a separate module, which shows that dmd is broken.
Nov 08 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkr12p$buk$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
Dave wrote:
 In article <dkqnr5$2tut$1 digitaldaemon.com>,
 =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
 
Garett Bass wrote:

With DMD 0.137, when I declare a function inside a private block, it remains
private for other modules, at least for my code.

Tom, It gets interesting here... ------------ module test; // test.d private void foo() { writefln("private test.foo()"); } ------------ module main; // main.d import test; int main(char[][] args) { //foo(); // Error: "module main test.foo is private" test.foo(); // OK, prints: "private test.foo()" return 0; } ------------ Do you think this is the intended behavior? I'm not sure that it is wrong, but I do find it surprising.

I think it's wrong. I have a feeling this has very much to do with the problems I've previously had with private imports not being all that private. Now, if only Walter could to a look at this ;)

I do too: "Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs." Looks like a compiler bug to me...

Here is a yet another simple test case: ====>test.cpp: #include <stdio.h> class m { private: static const int a = 5; }; int main() { printf("%d", m::a); return 0; } ====>test.java: class m { private static int a = 5; } public class m2 { public static void main(String[] p) { System.out.println(m.a); } } ====>test.d: class m { private static int a = 5; } void main() { printf("%d",m.a); }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.
test.cpp and test.java won't compile. They complain about the private 
keyword. test.d compiles nicely even with class m being a private class 
in a separate module, which shows that dmd is broken.

Regards Tom
Nov 08 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi wrote:


[snip]
 Ok, Regan showed me earlier that this (private member of a class in the same
 module) is accessible from anyplace in the enclosing module, so it's not a bug.
 (http://www.digitalmars.com/d/attribute.html)
 
 I personally think that this behavior is useless and confusing.

As near as I can figure it out, in D:- ** "private" means private to the module (source file), and not anything smaller. It can only be applied to class members and module members. ** "protected" is identical to "private" except for two differences. It can only be applied to class members, and it extends access to classes derived from a class that contains "protected" members. ** "package" means private to the package (source files in the same folder), and not anything smaller. It can only be applied to class members and module members. -- Derek (skype: derek.j.parnell) Melbourne, Australia 9/11/2005 2:50:20 PM
Nov 08 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system. Regan
Nov 08 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszygscna23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system.

What about having another attribute to allow other entities in the same module to gain access to that members? For example: module some_module; private class Aux { private: static int invisible_outside_class = 8; module: static int n = 5; static float f = 3.14; } public class ExportedObject { private float somesum = 0.0; public this() { somesum = Aux.n + Aux.f; // OK. somesum += Aux.invisible_outside_class; // ERROR, PRIVATE MEMBER ACCESS. } public float giveme_somesum() { return somesum; } } -------- module main; import some_module; int main() { int k = Aux.n; // ERROR, PRIVATE CLASS. int j = Aux.invisible_outside_class; // ERROR, PRIVATE CLASS. ExportedObject eo = new ExportedObject(); // OK (WITHOUT THE ERROR STATEMENT). float r = eo.giveme_somenum(); // OK. return 0; } Regards Tom
Nov 08 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 9 Nov 2005 05:12:23 +0000 (UTC), Tomás Rossi wrote:

 In article <opszygscna23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system.

What about having another attribute to allow other entities in the same module to gain access to that members? For example: module some_module; private class Aux { private: static int invisible_outside_class = 8; module: static int n = 5; static float f = 3.14; } public class ExportedObject { private float somesum = 0.0; public this() { somesum = Aux.n + Aux.f; // OK. somesum += Aux.invisible_outside_class; // ERROR, PRIVATE MEMBER ACCESS. } public float giveme_somesum() { return somesum; } } -------- module main; import some_module; int main() { int k = Aux.n; // ERROR, PRIVATE CLASS. int j = Aux.invisible_outside_class; // ERROR, PRIVATE CLASS. ExportedObject eo = new ExportedObject(); // OK (WITHOUT THE ERROR STATEMENT). float r = eo.giveme_somenum(); // OK. return 0; } Regards Tom

I think I'd prefer a new protection attribute to limit scope to within a class or struct. Something like ... class Aux { local: static int invisible_outside_class = 8; private: static int n = 5; static float f = 3.14; } And even rename "private" to "module" to make it more clear as to its scope. A further useful protection facility would be to make a class definition invisible to other source files. Currently the use of "private" on the "class" definition is ignored but it could be used to hide a class from other modules. The current technique of designating the class constructor as private is a bit obtuse and smacks of a "workaround fix" rather than a thought out solution to the real problem. -- Derek (skype: derek.j.parnell) Melbourne, Australia 9/11/2005 4:32:07 PM
Nov 08 2005
next sibling parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <rucuadlryr2z.1pa95y3b7yrr5$.dlg 40tude.net>, Derek Parnell says...
On Wed, 9 Nov 2005 05:12:23 +0000 (UTC), Tomás Rossi wrote:

 In article <opszygscna23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system.

What about having another attribute to allow other entities in the same module to gain access to that members? For example: module some_module; private class Aux { private: static int invisible_outside_class = 8; module: static int n = 5; static float f = 3.14; } public class ExportedObject { private float somesum = 0.0; public this() { somesum = Aux.n + Aux.f; // OK. somesum += Aux.invisible_outside_class; // ERROR, PRIVATE MEMBER ACCESS. } public float giveme_somesum() { return somesum; } } -------- module main; import some_module; int main() { int k = Aux.n; // ERROR, PRIVATE CLASS. int j = Aux.invisible_outside_class; // ERROR, PRIVATE CLASS. ExportedObject eo = new ExportedObject(); // OK (WITHOUT THE ERROR STATEMENT). float r = eo.giveme_somenum(); // OK. return 0; } Regards Tom

I think I'd prefer a new protection attribute to limit scope to within a class or struct. Something like ... class Aux { local: static int invisible_outside_class = 8; private: static int n = 5; static float f = 3.14; } And even rename "private" to "module" to make it more clear as to its scope.

Fine by me.
A further useful protection facility would be to make a class definition
invisible to other source files. Currently the use of "private" on the
"class" definition is ignored but it could be used to hide a class from
other modules. The current technique of designating the class constructor
as private is a bit obtuse and smacks of a "workaround fix" rather than a
thought out solution to the real problem.

Couldn't agree more on this.
-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
9/11/2005 4:32:07 PM

Tom
Nov 09 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use. The current D way offers no less control than "friend" in C++ but it offers it in a different way, instead of adding friend to a class you place it in the same module. Does Java have anything for the same purpose? perhaps inner classes? I'm no Java expert and I'm curious.
 A further useful protection facility would be to make a class definition
 invisible to other source files. Currently the use of "private" on the
 "class" definition is ignored but it could be used to hide a class from
 other modules. The current technique of designating the class constructor
 as private is a bit obtuse and smacks of a "workaround fix" rather than a
 thought out solution to the real problem.

That's cos it was a workaround ;) It would be nice to be able to hide a class with a single keyword in the logical place. It seems that place is on the class definition, I agree. Regan
Nov 09 2005
next sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use. The current D way offers no less control than "friend" in C++ but it offers it in a different way, instead of adding friend to a class you place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks). The friend approach gives you the advantage that you do not have to modify the source file of the class to which you want YOUR class to be friend (that could be a class not written by you or you may even just not have the source, maybe just the .obj or .lib (is this not possible?)). Correct me if i'm wrong please.
Does Java have anything for the same purpose? perhaps inner classes? I'm  
no Java expert and I'm curious.

 A further useful protection facility would be to make a class definition
 invisible to other source files. Currently the use of "private" on the
 "class" definition is ignored but it could be used to hide a class from
 other modules. The current technique of designating the class constructor
 as private is a bit obtuse and smacks of a "workaround fix" rather than a
 thought out solution to the real problem.

That's cos it was a workaround ;) It would be nice to be able to hide a class with a single keyword in the logical place. It seems that place is on the class definition, I agree.

Regards Tom
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to modify  
 the
 source file of the class to which you want YOUR class to be friend (that  
 could
 be a class not written by you or you may even just not have the source,  
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members. Regan
Nov 09 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
 I admin I am no C++ nor "friend" expert, it was my understanding that  
 friend operates like so:

TYPO: "admin" == "admit" Regan
Nov 09 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to modify  
 the
 source file of the class to which you want YOUR class to be friend (that  
 could
 be a class not written by you or you may even just not have the source,  
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to. Tom
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to modify
 the
 source file of the class to which you want YOUR class to be friend  
 (that
 could
 be a class not written by you or you may even just not have the source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators) I'm not that well versed in C++ (mostly a C programmer) so I haven't used these, nor do I know how they're constructed. Can you give a simplified example? Regan
Nov 09 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszz5jlgs23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to modify
 the
 source file of the class to which you want YOUR class to be friend  
 (that
 could
 be a class not written by you or you may even just not have the source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators)

Think I was pretty obvious here.
I'm not that well versed in C++ (mostly a C programmer) so I haven't used  
these, nor do I know how they're constructed. Can you give a simplified  
example?

I can give you a C++ not-compiled example (i'm opening the umbrella before it rains compiler errors or something): In C++ there can be more specific friendship relation, not only friend classes. Suppose I wrote a data structure, a container one: #include <iostream> #include "List.h" template <class T> class SimpleStack { private: List<T> m_list; public: SimpleStack() {} // Constructor. ~SimpleStack() {} // Destructor. size_t size() const { return m_list.size(); } void push(const T& element) { m_list.pushFront(element); } T pop() { return m_list.popFront(); } friend ostream &operator<< <T> (ostream &os, const SimpleStack<T> &ss); }; // Implementation. template <class T> ostream &operator<<(ostream &os, const SimpleStack<T> &ss) { List<T>::ConstIterator it = ss.m_lista.begin(); while (it != ss.m_lista.end()) { os << *it << endl; it++; // Advance iterator. } return os; } then you could use it as: int main() { SimpleStack<int> ss; ss.push(3); ss.push(-1); ss.push(2); cout << ss << endl; return 0; } As you see, SimpleStack is permitting (through a "friend" declaration) to implement an overloaded operator of ostream class, that causes you could just use the << operator to print to the screen the SS object within a single and nice line of code (a sort of toString()). Ok, it's a little to much for this discussion maybe, but it may help to get clearer ideas of one of the motivations for wich we do friend declarations. I know this is not the way D enforce to do things (with respect to streams and screen output, i guess), so don't give me a preaching about this. Tom
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 03:11:52 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz5jlgs23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class  
 you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to  
 modify
 the
 source file of the class to which you want YOUR class to be friend
 (that
 could
 be a class not written by you or you may even just not have the  
 source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators)

Think I was pretty obvious here.

Obviously not :)
 I'm not that well versed in C++ (mostly a C programmer) so I haven't  
 used
 these, nor do I know how they're constructed. Can you give a simplified
 example?


<snip> I understand what you mean now, you're saying C++ has friend functions as well as friend classes. So does D, any function in the same module as a class is a "friend" function. Regan
Nov 09 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszz9bmiy23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Thu, 10 Nov 2005 03:11:52 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz5jlgs23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath says...
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class  
 you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to  
 modify
 the
 source file of the class to which you want YOUR class to be friend
 (that
 could
 be a class not written by you or you may even just not have the  
 source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators)

Think I was pretty obvious here.

Obviously not :)

Ok, maybe I've assumed to much of your C++ knowledge here, sorry.
 I'm not that well versed in C++ (mostly a C programmer) so I haven't  
 used
 these, nor do I know how they're constructed. Can you give a simplified
 example?


<snip> I understand what you mean now, you're saying C++ has friend functions as well as friend classes. So does D, any function in the same module as a class is a "friend" function.

Yap! :D, I think now we are in the same train of thought ;) Thats what I meant. If you want to do something like this in D you just can't because you're not supposed to add code to std modules (that would be iostream in C++, a standard source files with standard objects the user isn't supposed to touch), or to add code to someone else's modules to make the friendship, that's obviously just an "YYYYAAACK, BAD BOY!" thing. Tom
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 04:00:38 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz9bmiy23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 03:11:52 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz5jlgs23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath  
 says...
 The current D way offers no less control than "friend" in C++ but  
 it
 offers it in a different way, instead of adding friend to a class
 you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to
 modify
 the
 source file of the class to which you want YOUR class to be friend
 (that
 could
 be a class not written by you or you may even just not have the
 source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators)

Think I was pretty obvious here.

Obviously not :)

Ok, maybe I've assumed to much of your C++ knowledge here, sorry.
 I'm not that well versed in C++ (mostly a C programmer) so I haven't
 used
 these, nor do I know how they're constructed. Can you give a  
 simplified
 example?


<snip> I understand what you mean now, you're saying C++ has friend functions as well as friend classes. So does D, any function in the same module as a class is a "friend" function.

Yap! :D, I think now we are in the same train of thought ;) Thats what I meant. If you want to do something like this in D you just can't because you're not supposed to add code to std modules (that would be iostream in C++, a standard source files with standard objects the user isn't supposed to touch), or to add code to someone else's modules to make the friendship, that's obviously just an "YYYYAAACK, BAD BOY!" thing.

Hold on. The code you posted had an operator<< overload, that overload was designated as a friend of SimpleStack<T> not of iostream, it has access to the private members of SimpleStack<T> not iostream. In order to achive that you had to modify SimpleStack<T> adding this line: friend ostream &operator<< <T> (ostream &os, const SimpleStack<T> &ss); It's no different in D, you would have to place the operator overload in the same module as the SimpleStack<T> class. Regan
Nov 09 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opsz0cvbvz23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Thu, 10 Nov 2005 04:00:38 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszz9bmiy23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 03:11:52 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz5jlgs23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Thu, 10 Nov 2005 01:48:56 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszz0bk0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 21:50:19 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 In article <opszzrvyj923k2f5 nrage.netwin.co.nz>, Regan Heath  
 says...
 The current D way offers no less control than "friend" in C++ but  
 it
 offers it in a different way, instead of adding friend to a class
 you
 place it in the same module.

What about if you have no access to the module source where lies the class to which you want your class to be friend with? (I know, my english sucks).

It's pretty good, that sentence is going to be confusing no matter how you say it.
 The
 friend approach gives you the advantage that you do not have to
 modify
 the
 source file of the class to which you want YOUR class to be friend
 (that
 could
 be a class not written by you or you may even just not have the
 source,
 maybe
 just the .obj or .lib (is this not possible?)).
 Correct me if i'm wrong please.

I admin I am no C++ nor "friend" expert, it was my understanding that friend operates like so: class A { private static int a; friend class B; }; class B { void foo() { a = 5; } }; class A specifies the friend who is allowed to access the private int 'a' and modify it. Without access to class A you cannot become a friend and access it's private members.

For an example of what I mean, take a look of iostreams << and >> operator overloading. That was to what i was referring to.

Take a look at what? the source code? (I assume you mean C++'s iostreams << and >> operators)

Think I was pretty obvious here.

Obviously not :)

Ok, maybe I've assumed to much of your C++ knowledge here, sorry.
 I'm not that well versed in C++ (mostly a C programmer) so I haven't
 used
 these, nor do I know how they're constructed. Can you give a  
 simplified
 example?


<snip> I understand what you mean now, you're saying C++ has friend functions as well as friend classes. So does D, any function in the same module as a class is a "friend" function.

Yap! :D, I think now we are in the same train of thought ;) Thats what I meant. If you want to do something like this in D you just can't because you're not supposed to add code to std modules (that would be iostream in C++, a standard source files with standard objects the user isn't supposed to touch), or to add code to someone else's modules to make the friendship, that's obviously just an "YYYYAAACK, BAD BOY!" thing.

Hold on. The code you posted had an operator<< overload, that overload was designated as a friend of SimpleStack<T> not of iostream, it has access to the private members of SimpleStack<T> not iostream. In order to achive that you had to modify SimpleStack<T> adding this line: friend ostream &operator<< <T> (ostream &os, const SimpleStack<T> &ss); It's no different in D, you would have to place the operator overload in the same module as the SimpleStack<T> class.

But in D you have to put BOTH OF THE TWO CLASSES in the same module. I never say you wouldn't have to modify your class. Suppose you have something like iostreams in D. And suppose they are part of Phobos. Now you want to write a SimpleStack and want to overload << operator for it to output to the screen in a SimpleStack custom way. Then just to achieve any friendship you'd have to write SimpleStack into iostream standard module (and I don't really think you can do that at all). That or I don't understand what are you trying to say. Regards Tom
Nov 10 2005
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Tomás Rossi wrote:
 
 But in D you have to put BOTH OF THE TWO CLASSES in the same module. I never
say
 you wouldn't have to modify your class. Suppose you have something like
 iostreams in D. And suppose they are part of Phobos. Now you want to write a
 SimpleStack and want to overload << operator for it to output to the screen in
a
 SimpleStack custom way. Then just to achieve any friendship you'd have to write
 SimpleStack into iostream standard module (and I don't really think you can do
 that at all). That or I don't understand what are you trying to say.

You can do the same thing in D, but the way you do it is a little bit different. class SimpleStack(T) { ostream opShl_r(ostream o) { o << something; return o; } private something; } as opShl_r is defined in SimpleStack it has access to SimpleStack's private parts. Hope this helps in this neverending discussion :)
Nov 10 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkvjhk$1dtg$1 digitaldaemon.com>, Ivan Senji says...
Tomás Rossi wrote:
 
 But in D you have to put BOTH OF THE TWO CLASSES in the same module. I never
say
 you wouldn't have to modify your class. Suppose you have something like
 iostreams in D. And suppose they are part of Phobos. Now you want to write a
 SimpleStack and want to overload << operator for it to output to the screen in
a
 SimpleStack custom way. Then just to achieve any friendship you'd have to write
 SimpleStack into iostream standard module (and I don't really think you can do
 that at all). That or I don't understand what are you trying to say.

You can do the same thing in D, but the way you do it is a little bit different. class SimpleStack(T) { ostream opShl_r(ostream o) { o << something; return o; } private something; } as opShl_r is defined in SimpleStack it has access to SimpleStack's private parts. Hope this helps in this neverending discussion :)

Ok, this beats specifically the << operator overloading example, but there could be another similar example that doesn't use an operator and instead use just a member function. I'll think about it and post it (if I found one). I doubt this specific example will puff out this nice discussion :) Tom
Nov 10 2005
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Tomás Rossi wrote:
 In article <dkvjhk$1dtg$1 digitaldaemon.com>, Ivan Senji says...
as opShl_r is defined in SimpleStack it has access to SimpleStack's 
private parts.

Hope this helps in this neverending discussion :)

Ok, this beats specifically the << operator overloading example, but there could be another similar example that doesn't use an operator and instead use just a member function. I'll think about it and post it (if I found one). I doubt this specific example will puff out this nice discussion :) Tom

Other than this what would be the case where you wish to grant some other (possibly library) class access to your classes private parts? I think that one can adjust to this /limitation/ in D. I don't even think it is a limitation, in most cases i wish my classes have friendship relationship and it is easy to accomplish that (put them in the same module). On the other topic i am starting to think that it would be nice to be able to split modules into more files. C# can now even split classes into more files but it is another discussion.
Nov 10 2005
next sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Ivan Senji wrote:
 Other than this what would be the case where you wish to grant some 
 other (possibly library) class access to your classes private parts?
 I think that one can adjust to this /limitation/ in D. I don't even 
 think it is a limitation, in most cases i wish my classes have 
 friendship relationship and it is easy to accomplish that (put them in 
 the same module).

I agree ;)
 
 On the other topic i am starting to think that it would be nice to be 
 able to split modules into more files. C# can now even split classes 
 into more files but it is another discussion.

But I thought we have packages already. I'm sure it's technically easy to support distributed module files. OTOH it's also possible to support multiple modules in a single file. I've used a text editor with code folding support for almost ten years now so having long source files isn't a problem. Can you come up with a practical example perhaps?
Nov 10 2005
prev sibling next sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkvsqj$1ndm$1 digitaldaemon.com>, Ivan Senji says...
Tomás Rossi wrote:
 In article <dkvjhk$1dtg$1 digitaldaemon.com>, Ivan Senji says...
as opShl_r is defined in SimpleStack it has access to SimpleStack's 
private parts.

Hope this helps in this neverending discussion :)

Ok, this beats specifically the << operator overloading example, but there could be another similar example that doesn't use an operator and instead use just a member function. I'll think about it and post it (if I found one). I doubt this specific example will puff out this nice discussion :) Tom

Other than this what would be the case where you wish to grant some other (possibly library) class access to your classes private parts? I think that one can adjust to this /limitation/ in D. I don't even think it is a limitation, in most cases i wish my classes have friendship relationship and it is easy to accomplish that (put them in the same module).

I still think it looks very dirty to allow other classes from the same module to touch private members of each others (IMHO this could be a nice feature but not to be the default behavior, maybe it should have a keyword behind it). What about all the nice contract programming features? PRE/POST-conditions and invariants? (just asking). I feel that this permissive behavior goes one step back just after going a step forward with contract programming. If it's ugly to break the invariant of a class inside it, imagine breaking it from the outside. I sincerely distrust of the feature. Quote: "in most cases i wish my classes have friendship relationship and it is easy to accomplish that". Yeah it's nice, but it'd be nicer if you could have more control of this in a more detailed way (e.g. adding more attributes or modifiers if it is necessary). I'm not saying this in-module-friendship is bad, just wish it to be optional to avoid the "paradox" it is (IMO) with respect to contract programming philosophy (not being to much of a scientist here, this is just what I perceive :) ). One advantage of friend keyword approach (e.g. C++) is that with it, you can control exactly WHO would you let to put their hands on the most intimate members of your object.
On the other topic i am starting to think that it would be nice to be 
able to split modules into more files. C# can now even split classes 
into more files but it is another discussion.

PS: stop with the "if you don't want any other entity to gain access to your class privates, put it on another module!", THE WORLD ISN'T JUST BLACK OR WHITE. Tom
Nov 10 2005
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Tomás Rossi wrote:
 In article <dkvsqj$1ndm$1 digitaldaemon.com>, Ivan Senji says...
 
Tomás Rossi wrote:

In article <dkvjhk$1dtg$1 digitaldaemon.com>, Ivan Senji says...

as opShl_r is defined in SimpleStack it has access to SimpleStack's 
private parts.

Hope this helps in this neverending discussion :)

Ok, this beats specifically the << operator overloading example, but there could be another similar example that doesn't use an operator and instead use just a member function. I'll think about it and post it (if I found one). I doubt this specific example will puff out this nice discussion :) Tom

Other than this what would be the case where you wish to grant some other (possibly library) class access to your classes private parts? I think that one can adjust to this /limitation/ in D. I don't even think it is a limitation, in most cases i wish my classes have friendship relationship and it is easy to accomplish that (put them in the same module).

I still think it looks very dirty to allow other classes from the same module to touch private members of each others

In a strict OO sense friendship is allways dirty.
 (IMHO this could be a nice feature but not
 to be the default behavior, maybe it should have a keyword behind it). What
 about all the nice contract programming features? PRE/POST-conditions and
 invariants? (just asking). I feel that this permissive behavior goes one step
 back just after going a step forward with contract programming. If it's ugly to
 break the invariant of a class inside it, imagine breaking it from the outside.
 I sincerely distrust of the feature.
 
 Quote: "in most cases i wish my classes have friendship relationship and it is
 easy to accomplish that". 
 Yeah it's nice, but it'd be nicer if you could have more control of this in a
 more detailed way (e.g. adding more attributes or modifiers if it is
necessary).
 I'm not saying this in-module-friendship is bad, just wish it to be optional to
 avoid the "paradox" it is (IMO) with respect to contract programming philosophy
 (not being to much of a scientist here, this is just what I perceive :) ). One
 advantage of friend keyword approach (e.g. C++) is that with it, you can
control
 exactly WHO would you let to put their hands on the most intimate members of
 your object.
 
 
On the other topic i am starting to think that it would be nice to be 
able to split modules into more files. C# can now even split classes 
into more files but it is another discussion.

PS: stop with the "if you don't want any other entity to gain access to your class privates, put it on another module!", THE WORLD ISN'T JUST BLACK OR WHITE.

I think the problem here is (i had it too when i started with D) that you are trying/wanting to write C++, but this is another language and there are different ways to do things. The philosophy here is: make simple things simple and the D way gives you full control. If you want to have friend classes in D you have to put them in the same model. The rule in C++ is different: if you want firendsip use the friendship keyword. The D way is a little bit more limiting in that you can't make someone elses (or library) classes your firends but that would IMO be a bad design decision anyway. D makes you stick to the OO paradigm when using other peoples classes (wich is ok), but also allows you to cheat OO in your code (also ok). So your code in one module has default friendship, and doesn't it make sense? It is after all a group of related classes that are placed in one module. And if you really really don't want any other entity to gain access to your class privates, put it on another module. :) HM, this sentence sounds familiar ;) Conclusion: Give The-D-Way a chance, it might make sense to you in a while.
Nov 10 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Fri, 11 Nov 2005 00:24:50 +0100, Ivan Senji wrote:


[snip]
 And if you really really don't want any other entity to gain access to 
 your class privates, put it on another module. :) HM, this sentence 
 sounds familiar ;)

Yes, in principle I agree with you. But how can you provide access to parts of a class but not other parts of the class? With D, its the whole class or nothing. Splitting the class into two or more classes is not always a sensible thing to do either. -- Derek (skype: derek.j.parnell) Melbourne, Australia 11/11/2005 10:26:41 AM
Nov 10 2005
prev sibling parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dl0ks3$2dae$1 digitaldaemon.com>, Ivan Senji says...
Tomás Rossi wrote:
 In article <dkvsqj$1ndm$1 digitaldaemon.com>, Ivan Senji says...
 
Tomás Rossi wrote:

In article <dkvjhk$1dtg$1 digitaldaemon.com>, Ivan Senji says...

as opShl_r is defined in SimpleStack it has access to SimpleStack's 
private parts.

Hope this helps in this neverending discussion :)

Ok, this beats specifically the << operator overloading example, but there could be another similar example that doesn't use an operator and instead use just a member function. I'll think about it and post it (if I found one). I doubt this specific example will puff out this nice discussion :) Tom

Other than this what would be the case where you wish to grant some other (possibly library) class access to your classes private parts? I think that one can adjust to this /limitation/ in D. I don't even think it is a limitation, in most cases i wish my classes have friendship relationship and it is easy to accomplish that (put them in the same module).

I still think it looks very dirty to allow other classes from the same module to touch private members of each others

In a strict OO sense friendship is allways dirty.
 (IMHO this could be a nice feature but not
 to be the default behavior, maybe it should have a keyword behind it). What
 about all the nice contract programming features? PRE/POST-conditions and
 invariants? (just asking). I feel that this permissive behavior goes one step
 back just after going a step forward with contract programming. If it's ugly to
 break the invariant of a class inside it, imagine breaking it from the outside.
 I sincerely distrust of the feature.
 
 Quote: "in most cases i wish my classes have friendship relationship and it is
 easy to accomplish that". 
 Yeah it's nice, but it'd be nicer if you could have more control of this in a
 more detailed way (e.g. adding more attributes or modifiers if it is
necessary).
 I'm not saying this in-module-friendship is bad, just wish it to be optional to
 avoid the "paradox" it is (IMO) with respect to contract programming philosophy
 (not being to much of a scientist here, this is just what I perceive :) ). One
 advantage of friend keyword approach (e.g. C++) is that with it, you can
control
 exactly WHO would you let to put their hands on the most intimate members of
 your object.
 
 
On the other topic i am starting to think that it would be nice to be 
able to split modules into more files. C# can now even split classes 
into more files but it is another discussion.

PS: stop with the "if you don't want any other entity to gain access to your class privates, put it on another module!", THE WORLD ISN'T JUST BLACK OR WHITE.

I think the problem here is (i had it too when i started with D) that you are trying/wanting to write C++, but this is another language and there are different ways to do things. The philosophy here is: make simple things simple and the D way gives you full control. If you want to have friend classes in D you have to put them in the same model. The rule in C++ is different: if you want firendsip use the friendship keyword. The D way is a little bit more limiting in that you can't make someone elses (or library) classes your firends but that would IMO be a bad design decision anyway. D makes you stick to the OO paradigm when using other peoples classes (wich is ok), but also allows you to cheat OO in your code (also ok). So your code in one module has default friendship, and doesn't it make sense? It is after all a group of related classes that are placed in one module. And if you really really don't want any other entity to gain access to your class privates, put it on another module. :) HM, this sentence sounds familiar ;)

Not again! :D
Conclusion: Give The-D-Way a chance, it might make sense to you in a while.

Ok, I'll try. It'll be hard to accept it... after all, having some keywords to do what I ask is just a proposal... in the future it could be taken in account :) Tom
Nov 10 2005
prev sibling parent Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Ivan Senji wrote:
 C# can now even split classes 
 into more files but it is another discussion.

-- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Nov 11 2005
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 10 Nov 2005 10:13:00 +1300, Regan Heath wrote:

 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use.

Huh? You seem to be trying to complicate this to make it look silly. I disagree that one needs to do all the twisting and mashing of keywords and concepts you just described. Simply leave everything as it is now, and add a "local" attribute to designate those members whose scope is only the enclosing class/struct. That's it! You then get all the benefits of current D philosophy plus the added concept of reduced bonding amongst class in the same module. Using this "local" concept, it still allows two classes in the same module to have access to "private" members but not access to "local" members.
 The current D way offers no less control than "friend" in C++ but it  
 offers it in a different way, instead of adding friend to a class you  
 place it in the same module.

Yes, exactly. And that is the problem. It forces one to place 'friend' classes into the same module, but by doing that one also increases the cost of maintenance by implicitly increasing the binding between such classes.
 Does Java have anything for the same purpose? perhaps inner classes? I'm  
 no Java expert and I'm curious.

Maybe inner classes are the solution. I don't know as I haven't really explored this yet. -- Derek Parnell Melbourne, Australia 10/11/2005 8:46:17 AM
Nov 09 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 08:53:50 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 10 Nov 2005 10:13:00 +1300, Regan Heath wrote:

 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 I think I'd prefer a new protection attribute to limit scope to within  
 a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use.

Huh? You seem to be trying to complicate this to make it look silly.I disagree that one needs to do all the twisting and mashing of keywords and concepts you just described. Simply leave everything as it is now, and add a "local" attribute to designate those members whose scope is only the enclosing class/struct. That's it! You then get all the benefits of current D philosophy plus the added concept of reduced bonding amongst class in the same module.

If your intention is to stop confusing C++ developers then this isn't going to work IMO. They're going to continue to use "private" and expect C++ behaviour. Sure, now they have "local" to achieve C++ private, but the problem remains how do they get C++ protected within a module? If your suggestion is just an idea to get C++ private behaviour and to get it with a _different_ keyword, fine, I just see no merit in that, personally. My suggestion was based on the way I see the D system working, in my opinion "private" etc work exactly how they work in C++ _except_ there is a blanket effect "friend" for all code within a module. You can make it the same as C++ by removing that blanket effect. Your suggestion creates an exception to the blanket effect, one that is essentially "private" minus the blanket effect. That is how I see it operating, perhaps you see it differently?
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.

Yes, exactly. And that is the problem. It forces one to place 'friend' classes into the same module, but by doing that one also increases the cost of maintenance by implicitly increasing the binding between such classes.

Explain how it "implicitly increas(es) the binding between such classes"? I am assuming here we're comparing 2 C++ friend classes and 2 D classes in the same module, how is the D method "increased binding"? Further, how does it increase the cost of maintenance? Regan
Nov 09 2005
next sibling parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 On Thu, 10 Nov 2005 08:53:50 +1100, Derek Parnell <derek psych.ward> wrote:
 
 On Thu, 10 Nov 2005 10:13:00 +1300, Regan Heath wrote:

 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward>  
 wrote:

 I think I'd prefer a new protection attribute to limit scope to 
 within  a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use.

Huh? You seem to be trying to complicate this to make it look silly.I disagree that one needs to do all the twisting and mashing of keywords and concepts you just described. Simply leave everything as it is now, and add a "local" attribute to designate those members whose scope is only the enclosing class/struct. That's it! You then get all the benefits of current D philosophy plus the added concept of reduced bonding amongst class in the same module.

If your intention is to stop confusing C++ developers then this isn't going to work IMO. They're going to continue to use "private" and expect C++ behaviour. Sure, now they have "local" to achieve C++ private, but the problem remains how do they get C++ protected within a module?

I think the C++ -users are fully able to RTFM whenever they need some guidance. To simplify the D visibility keywords, I've created some nice charts [1] based on [2]. You don't need a local-keyword since you can limit the visibility of private members using the module system (actually this requires Walter to fix the pending visibility bug) [1] http://users.utu.fi/jmjmak/d/ [2] http://www.digitalmars.com/d/attribute.html
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 03:05:20 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 On Thu, 10 Nov 2005 08:53:50 +1100, Derek Parnell <derek psych.ward>  
 wrote:

 On Thu, 10 Nov 2005 10:13:00 +1300, Regan Heath wrote:

 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward>   
 wrote:

 I think I'd prefer a new protection attribute to limit scope to  
 within  a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use.

Huh? You seem to be trying to complicate this to make it look silly.I disagree that one needs to do all the twisting and mashing of keywords and concepts you just described. Simply leave everything as it is now, and add a "local" attribute to designate those members whose scope is only the enclosing class/struct. That's it! You then get all the benefits of current D philosophy plus the added concept of reduced bonding amongst class in the same module.

isn't going to work IMO. They're going to continue to use "private" and expect C++ behaviour. Sure, now they have "local" to achieve C++ private, but the problem remains how do they get C++ protected within a module?

I think the C++ -users are fully able to RTFM whenever they need some guidance.

Sure, but they will still have to rewire their brains to adopt the new system. To be clear I wasn't suggesting we change it, I was just re-working Derek's solution to be more useful (as I saw it).
 To simplify the D visibility keywords, I've created some nice charts [1]  
 based on [2]. You don't need a local-keyword since you can limit the  
 visibility of private members using the module system (actually this  
 requires Walter to fix the pending visibility bug)

 [1] http://users.utu.fi/jmjmak/d/
 [2] http://www.digitalmars.com/d/attribute.html

I like it. One point however. Is there a difference between "visible" and "accessable"? It seems "private" makes an instance (not a definition, yet?) "inaccessable" but not "invisible", this is shown by the sort of error message given when you try to access a "private" instance. D's docs say that "private" replaces "static" but doesn't "static" actually make an instance or declaration "invisible" as opposed to simply making it "inaccessable", it seems "private" in D does not cover everything that "static" did and that is why we're arguing about it ;) Regan Regan
Nov 09 2005
parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 One point however. Is there a difference between "visible" and  
 "accessable"? It seems "private" makes an instance (not a definition,  
 yet?) "inaccessable" but not "invisible", this is shown by the sort of  
 error message given when you try to access a "private" instance.
 
 D's docs say that "private" replaces "static" but doesn't "static"  
 actually make an instance or declaration "invisible" as opposed to 
 simply  making it "inaccessable", it seems "private" in D does not 
 cover  everything that "static" did and that is why we're arguing about 
 it ;)

Yes, that's true. The docs don't cover this issue very much. So you mean that although module a; private int i=42; module b: import a; printf("%d",i); //illegal is illegal, this example module a; private int i=42; module b: import a; printf("%d",b.i); //maybe legal might not be (at the moment). I hope Walter has time to write better documentation. Now he focuses too much on class member visibility issues.
Nov 10 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 10:01:39 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 One point however. Is there a difference between "visible" and   
 "accessable"? It seems "private" makes an instance (not a definition,   
 yet?) "inaccessable" but not "invisible", this is shown by the sort of   
 error message given when you try to access a "private" instance.
  D's docs say that "private" replaces "static" but doesn't "static"   
 actually make an instance or declaration "invisible" as opposed to  
 simply  making it "inaccessable", it seems "private" in D does not  
 cover  everything that "static" did and that is why we're arguing about  
 it ;)

Yes, that's true. The docs don't cover this issue very much. So you mean that although module a; private int i=42; module b: import a; printf("%d",i); //illegal is illegal, this example module a; private int i=42; module b: import a; printf("%d",b.i); //maybe legal might not be (at the moment).

I think both are equally illegal. I think this last one is simply a bug. What I was trying to say is that there is a difference between "invisible" and "inaccessable" a private variable is inaccessable but not invisible, this is why you get an error like: [invis_a.d] private int a; [invis.d] void main() { a = 5; //invis.d: module invis invis_a.a is private } the compiler knows what 'a' you're talking about, it just wont let you, because it's "inaccessable". as opposed to this from C: [a.c] static int a; [test.c] extern int a; void main() { a = 5; //test.obj : error LNK2001: unresolved external symbol _a } Here the compiler has no idea what 'a' you're talking about, it doesn't exist in this context, it's "invisible". The difference is that static in C prevents the symbol 'a' from being visible outside the file a.c, whereas private in D simply prevents access to it. In C 'a' is invisible, in D 'a' is inaccessable. I don't believe the D docs are 100% correct when they say: http://www.digitalmars.com/d/attribute.html "Private module members are equivalent to static declarations in C programs." Regan
Nov 10 2005
parent =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 What I was trying to say is that there is a difference between 
 "invisible"  and "inaccessable" a private variable is inaccessable but 
 not invisible,  this is why you get an error like:
 
 [invis_a.d]
 private int a;
 
 [invis.d]
 void main()
 {
   a = 5; //invis.d: module invis invis_a.a is private
 }
 
 the compiler knows what 'a' you're talking about, it just wont let you,  
 because it's "inaccessable".
 as opposed to this from C:
 
 [a.c]
 static int a;
 
 [test.c]
 extern int a;
 
 void main()
 {
     a = 5; //test.obj : error LNK2001: unresolved external symbol _a
 }
 
 Here the compiler has no idea what 'a' you're talking about, it doesn't  
 exist in this context, it's "invisible".
 
 The difference is that static in C prevents the symbol 'a' from being  
 visible outside the file a.c, whereas private in D simply prevents 
 access  to it. In C 'a' is invisible, in D 'a' is inaccessable.

Ok, now I got it :) Yes of course, D & Java compilers have much more knowledge of symbols than the primitive C compiler. That's because D uses symbol tables, it doesn't just cut'n'paste those include-files.
 I don't believe the D docs are 100% correct when they say:
 http://www.digitalmars.com/d/attribute.html
 
 "Private module members are equivalent to static declarations in C  
 programs."

I think it's bad practice to write docs that describe the functionality of the language by referring to other languages. Now you need to understand the concepts of several languages to understand D.
Nov 10 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 10 Nov 2005 13:09:33 +1300, Regan Heath wrote:


[snip] 
 If your intention is to stop confusing C++ developers then this isn't  
 going to work IMO. 

LOL! You are very correct, but I'm not regarding C++ coders as a "protected" species. My position is that if you want to learn a new language then learn it, and don't expect it to be the same as what you already know. So I don't care if some C++ coders find it hard to adapt to a new language. I realize that Walter and most others here are not of this opinion.
 They're going to continue to use "private" and expect  
 C++ behaviour. 

Are you implying that C++ coders innately find it hard to learn new languages? ;-)
Sure, now they have "local" to achieve C++ private, but the  
 problem remains how do they get C++ protected within a module?

I haven't really talked about 'protected' behaviour, just lexical scope so far. I'm not sure that I see 'private' and 'protected' as mutually exclusive. One deals with lexical scope and the other deals with inheritance scope. Is there any reason (conceptually) why a member cannot have both attributes? That is, a member could be designated as invisible outside the module *and* invisible to derived classes. I know that's not how D works now, but I'm talking conceptually.
 If your suggestion is just an idea to get C++ private behaviour and to get  
 it with a _different_ keyword, fine, I just see no merit in that,  
 personally.

Repeat after me ... D is not C++ ... D is not Java ... D is not C++ ... D is not Java ... D is not C++ ... D is not Java ... <G>
 My suggestion was based on the way I see the D system working, in my  
 opinion "private" etc work exactly how they work in C++ _except_ there is  
 a blanket effect "friend" for all code within a module. You can make it  
 the same as C++ by removing that blanket effect.
 
 Your suggestion creates an exception to the blanket effect, one that is  
 essentially "private" minus the blanket effect.
 
 That is how I see it operating, perhaps you see it differently?

Conceptually, without prejudice to any specific keyword, I see lexical scoping thusly ... (A) Limited to enclosing block. (B) Limited to enclosing container, i.e. class or struct. (C) Limited to enclosing file, i.e. module. (D) Limited to enclosing directory, i.e. package. (E) Limited to enclosing application, i.e. the executable. (F) Not limited to anything. Currently the D language supports all but (B). Now another type of scoping, which is orthogonal to the above, is inheritance scoping. This is just see as making a member 'visible' to derived classes or not.
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.



I do find D's restriction that a module is the same as a source file is a problem. If somehow you could have multiple files comprise a single module then the 'friend' concept might be easier to implement.
 Yes, exactly. And that is the problem. It forces one to place 'friend'
 classes into the same module, but by doing that one also increases the  
 cost of maintenance by implicitly increasing the binding between such  
 classes.

Explain how it "implicitly increas(es) the binding between such classes"?

If you have two classes in the same file, then all the code in either class can see all the members in the other class, implicitly. You don't have to make them explicitly visible to each other. (Not sure how nested/inner classes effect this).
 I am assuming here we're comparing 2 C++ friend classes and 2 D classes in  
 the same module, how is the D method "increased binding"? 

It doesn't increase it in D more than in C++. The increase is the same in both languages. I'm not comparing C++ with D here. The increase I'm talking about is just there because the class members are there. For example, imagine that I have a file with one class. I later come along an add another class to the same file. Currently, just be doing that, I bind (conceptually) the two classes together because each can see the internals of the other. However, further imagine that the default behaviour was that each class in a module does *not* expose its internals to other classes in the module. In that case, the classes are not bound to each other. If you then explicitly exposes selected members, you can control the limits of the binding, and thus control maintenance concerns.
Further, how  
 does it increase the cost of maintenance?

The computer science literature has for many years noted that 'module' binding is proportional to the complexity of the code. If you reduce the bindings you reduce the complexity, and reducing complexity can reduce maintenance costs. -- Derek (skype: derek.j.parnell) Melbourne, Australia 10/11/2005 11:38:51 AM
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 12:06:02 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 10 Nov 2005 13:09:33 +1300, Regan Heath wrote:
 [snip]
 If your intention is to stop confusing C++ developers then this isn't
 going to work IMO.

LOL! You are very correct, but I'm not regarding C++ coders as a "protected" species. My position is that if you want to learn a new language then learn it, and don't expect it to be the same as what you already know. So I don't care if some C++ coders find it hard to adapt to a new language. I realize that Walter and most others here are not of this opinion.

Don't go putting me into a basket just yet! The reason I mention C++ is not because I think we need to protect anyone, rather the OP is a C++ programmer (I believe) and mentioned they found the D system confusing, I quote: "I personally think that this behavior is useless and confusing." Aside: Realistically, the easier D is to adopt, the more people will do it. The 2 or perhaps 3 big groups which could adopt are C++, Java and C# programmers.
 Sure, now they have "local" to achieve C++ private, but the
 problem remains how do they get C++ protected within a module?

I haven't really talked about 'protected' behaviour, just lexical scope so far. I'm not sure that I see 'private' and 'protected' as mutually exclusive. One deals with lexical scope

I dont think it's "lexical" scope. The symbol is still visible outside that scope, access to it is simply prevented so it's more like "access" scope. If the symbol were not visible outside the scope you'd get a symbol not found error as opposed to the access denied style error you actually get.
 and the other deals with
 inheritance scope.

In both cases I believe it's "access" scope. This is the reason applying private to a class definition doesn't work, I believe, because it is a slightly different concept, you're actually hiding something as opposed to restricting access to something which isn't actually hidden. The D documentation does state that private replaces the C/C++ static, now, I believe static actually hides the variable, which in turn prevents access. I'm not sure D's private covers all of static yet.
 Is there any reason (conceptually) why a member cannot
 have both attributes? That is, a member could be designated as invisible
 outside the module *and* invisible to derived classes. I know that's not
 how D works now, but I'm talking conceptually.

Sure, but I think there is a difference between "invisible" and "inaccessable". <snip>
 The current D way offers no less control than "friend" in C++ but it
 offers it in a different way, instead of adding friend to a class you
 place it in the same module.



I do find D's restriction that a module is the same as a source file is a problem. If somehow you could have multiple files comprise a single module then the 'friend' concept might be easier to implement.

This is a seperate topic, doesn't "package" help here? (lets no take this further in this thread, it's large enough as is)
 Yes, exactly. And that is the problem. It forces one to place 'friend'
 classes into the same module, but by doing that one also increases the
 cost of maintenance by implicitly increasing the binding between such
 classes.

Explain how it "implicitly increas(es) the binding between such classes"?

If you have two classes in the same file, then all the code in either class can see all the members in the other class, implicitly.

Here is the root of the disagreement, IMO placing classes in the same module _is_ explicitly asking for them to be visible to each other, by definition.
 You don't have to
 make them explicitly visible to each other. (Not sure how nested/inner
 classes effect this).

 I am assuming here we're comparing 2 C++ friend classes and 2 D classes  
 in
 the same module, how is the D method "increased binding"?

It doesn't increase it in D more than in C++. The increase is the same in both languages. I'm not comparing C++ with D here. The increase I'm talking about is just there because the class members are there. For example, imagine that I have a file with one class. I later come along an add another class to the same file. Currently, just be doing that, I bind (conceptually) the two classes together because each can see the internals of the other. However, further imagine that the default behaviour was that each class in a module does *not* expose its internals to other classes in the module. In that case, the classes are not bound to each other. If you then explicitly exposes selected members, you can control the limits of the binding, and thus control maintenance concerns.
 Further, how
 does it increase the cost of maintenance?

The computer science literature has for many years noted that 'module' binding is proportional to the complexity of the code. If you reduce the bindings you reduce the complexity, and reducing complexity can reduce maintenance costs.

What exactly are you comparing here? You seem to be comparing "classes bound by D's module system" with "classes not bound by D's module system". I think that comparison is pointless, aren't we assuming the binding is required in some case, and if so shouldn't we be comparing different methods to achieve that binding? If so, aren't we comparing D's module method with C++'s "friend" method, Java's (just like D) package method and your suggested "local" method. I've already shown how your suggestion lacks a solution for 'protected' members, and then I suggested a change (which you thought was overly complicated). I prefer D's method for it's simplicity. Regan
Nov 09 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 10 Nov 2005 15:06:17 +1300, Regan Heath wrote:

[big snip]

It would seem that we are not on the same wave length and I don't think I
can express myself well enough. 
 
 I prefer D's method for it's simplicity.

Me too! I just don't get what it is you can't understand in my text. I too am saying that D is got it mostly right! I would not want it to change its current behaviour or keywords --- with one tiny exception --- allow a new keyword to designate which class member are ONLY *accessible* to other members in that same class and to no other code anywhere. Real example: I have a module that contains three class. These are big classes with lot's of functionality. This makes for a largish source file. They are in the same module because I *want* the D 'friend' behaviour for most of the members - for performance reasons mainly. However some members in one of the classes are strictly for the sole use of the code inside that class. And to save myself making mistakes, I'd love to designate those members as 'local' to the class and thus have the compiler trip over if I accidentally try to use them elsewhere. D does not support this form of self-protection. It doesn't mean that I can't write the application, but it does mean that I have greater chance of making a mistake. A compiler is also a tool to help people make fewer mistakes. -- Derek (skype: derek.j.parnell) Melbourne, Australia 10/11/2005 1:36:15 PM
Nov 09 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 13:51:15 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 10 Nov 2005 15:06:17 +1300, Regan Heath wrote:

 [big snip]

 It would seem that we are not on the same wave length and I don't think I
 can express myself well enough.

 I prefer D's method for it's simplicity.

Me too!

I know!
 I just don't get what it is you can't understand in my text. I too am
 saying that D is got it mostly right! I would not want it to change its
 current behaviour or keywords --- with one tiny exception --- allow a new
 keyword to designate which class member are ONLY *accessible* to other
 members in that same class and to no other code anywhere.

I know! My point, (which Tomás understood) is that your idea isn't flexible enough. It does not handle "protected" members i.e. a member which is protected externally but private or public internally. eg [module.d] class A { protected int a; } class B { } [other.d] class C : A { } "local" cannot hide 'a' from class B and remain 'protected' in class C. That is why I suggested making local a modifier for "private" etc, because then it can, eg. [module.d] class A { local protected int a; } class B { } [other.d] class C : A { } you took my suggestion as an attempt to make your idea more complex, which I guess it does, but it also makes it a whole lot more useful. Regan
Nov 09 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <inotc4h6h02k$.16dk251xzdhwx.dlg 40tude.net>, Derek Parnell says...
On Thu, 10 Nov 2005 10:13:00 +1300, Regan Heath wrote:

 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.

I think to make changes you first have to remove the "constantly in effect" module-friend-public access which is applied, this effect modifies all the existing protection attributes, making them all "public" for code in the same module. Once removed "private", "protected", and of course "public" would have the same meaning as in C++. Then, you could add "module" which would be "private" for code exterior to this module and "public" for code within the module. This would be the least confusing for a C++ developer coming to D I believe. But, the problem with this idea is that it isn't flexible enough. Say you have a class: class Foo { private int a; protected int b; public int c; } and you need access to 'b' in this module? you can't use "module" as that makes it "private" outside the module, not "protected". So, the next logical step is to make "module" a modifier for the other 3 protection attributes. That eventuality is worse than the C++ "friend" situation I feel, it does give more fine grained control but it's more verbose and fiddly as a result. In comparison the current D way is less fine grained but also much easier to use.

Huh? You seem to be trying to complicate this to make it look silly. I disagree that one needs to do all the twisting and mashing of keywords and concepts you just described. Simply leave everything as it is now, and add a "local" attribute to designate those members whose scope is only the enclosing class/struct. That's it! You then get all the benefits of current D philosophy plus the added concept of reduced bonding amongst class in the same module.

I agree, but i think i understood what Regan was trying to explain. Suppose you have something like this: -------------------------------------------------------------- module some_module; class A { protected char[] name="class A"; } // Base class. class B : A { public this() { name="class B"; } // Derived. class C : A { public this() { name="class C"; } // Derived. // Don't wanna let X gain access to protected member 'name' nor to any // other member of A, B or C that is not public, etc. class X { ... bla bla bla ... } -------------------------------------------------------------- Clearly, if you want to let 'B' and 'C' gain access to 'name', you cannot declare it 'local' you'll have rather declare it 'protected'. But this will leave it visible to the other classes of the module. And what i understood from what Regan said: -------------------------------------------------------------- module some_module; class A { local protected char[] name="class A"; } // Base class. class B : A { public this() { name="class B"; } // Derived. class C : A { public this() { name="class C"; } // Derived. // X will not have access to 'A.name', 'B.name' or 'C.name'. class X { ... bla bla bla ... } --------------------------------------------------------------
Using this "local" concept, it still allows two classes in the same module
to have access to "private" members but not access to "local" members. 

 The current D way offers no less control than "friend" in C++ but it  
 offers it in a different way, instead of adding friend to a class you  
 place it in the same module.

Yes, exactly. And that is the problem. It forces one to place 'friend' classes into the same module, but by doing that one also increases the cost of maintenance by implicitly increasing the binding between such classes.
 Does Java have anything for the same purpose? perhaps inner classes? I'm  
 no Java expert and I'm curious.

Maybe inner classes are the solution. I don't know as I haven't really explored this yet. -- Derek Parnell Melbourne, Australia 10/11/2005 8:46:17 AM

Tom
Nov 09 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 00:17:44 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 I agree, but i think i understood what Regan was trying to explain.

Yes, you have. Regan
Nov 09 2005
prev sibling parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Tomás Rossi wrote:
 I agree, but i think i understood what Regan was trying to explain. Suppose you
 have something like this:
 
 --------------------------------------------------------------
 module some_module;
 
 class A { protected char[] name="class A"; } // Base class.
 class B : A { public this() { name="class B"; } // Derived.
 class C : A { public this() { name="class C"; } // Derived.
 
 // Don't wanna let X gain access to protected member 'name' nor to any
 // other member of A, B or C that is not public, etc.
 class X { ... bla bla bla ... }
 --------------------------------------------------------------
 
 Clearly, if you want to let 'B' and 'C' gain access to 'name', you cannot
 declare it 'local' you'll have rather declare it 'protected'. But this will
 leave it visible to the other classes of the module.

Why do you have to keep the class X in the same module with classes A,B and C? It seems to me that class X is definitely not a friend class of any of the first three. You can minimize the abuse of D modules by doing: module some_module; class A { protected char[] name="class A"; } // Base class. class B : A { public this() { name="class B"; } // Derived. class C : A { public this() { name="class C"; } // Derived. module x_module; class X { ... bla bla bla ... }
Nov 09 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dku5ps$2pp7$2 digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
Tomás Rossi wrote:
 I agree, but i think i understood what Regan was trying to explain. Suppose you
 have something like this:
 
 --------------------------------------------------------------
 module some_module;
 
 class A { protected char[] name="class A"; } // Base class.
 class B : A { public this() { name="class B"; } // Derived.
 class C : A { public this() { name="class C"; } // Derived.
 
 // Don't wanna let X gain access to protected member 'name' nor to any
 // other member of A, B or C that is not public, etc.
 class X { ... bla bla bla ... }
 --------------------------------------------------------------
 
 Clearly, if you want to let 'B' and 'C' gain access to 'name', you cannot
 declare it 'local' you'll have rather declare it 'protected'. But this will
 leave it visible to the other classes of the module.

Why do you have to keep the class X in the same module with classes A,B and C? It seems to me that class X is definitely not a friend class of any of the first three.

I think no one could assure that X should (or shouldn't) be friend of A, B or C, because they are just generic examples and incomplete one´s as well. Meaningless objects wouldn't give you a clue for if they should be friends or not. Besides, this was not a piece of code to justify the "local" or "module" attribute proposal.
You can minimize the abuse of D modules by doing:

module some_module;

class A { protected char[] name="class A"; } // Base class.
class B : A { public this() { name="class B"; } // Derived.
class C : A { public this() { name="class C"; } // Derived.

module x_module;
class X { ... bla bla bla ... }

This is a nice thing and was a good thing to mention. Regards Tom
Nov 09 2005
prev sibling next sibling parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 Does Java have anything for the same purpose? perhaps inner classes? 
 I'm  no Java expert and I'm curious.

Java does have a similar system using packages. You can declare a top-level class as public/package (no keyword). Only one public class per package (module) is allowed, other classes must be "hidden" so that they're not polluting the namespace when the package is imported. Therefore only public classes are accessible from other modules. You need to explicitely write the "package foobar" line inside the source to use packages. You can also use inner & nested classes in Java. A nested class is a static class inside another class. You may declare nested class as private/protected/... just like any static class member. Private nested class isn't accessible outside the outer class. Inner classes are dynamic classes inside class objects that usually inherit some common interface. You may declare inner class as private/protected/... just like any class member. Declaring the inner class as private means that you only can use the inner class via Object/superclass-methods since the class declaration is hidden. I think the package system in Java is ok and the current D implementation is broken. I have an example in one of my previous posts.
Nov 09 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 01:33:14 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 Does Java have anything for the same purpose? perhaps inner classes?  
 I'm  no Java expert and I'm curious.

Java does have a similar system using packages. You can declare a top-level class as public/package (no keyword). Only one public class per package (module) is allowed, other classes must be "hidden" so that they're not polluting the namespace when the package is imported. Therefore only public classes are accessible from other modules. You need to explicitely write the "package foobar" line inside the source to use packages. You can also use inner & nested classes in Java. A nested class is a static class inside another class. You may declare nested class as private/protected/... just like any static class member. Private nested class isn't accessible outside the outer class. Inner classes are dynamic classes inside class objects that usually inherit some common interface. You may declare inner class as private/protected/... just like any class member. Declaring the inner class as private means that you only can use the inner class via Object/superclass-methods since the class declaration is hidden. I think the package system in Java is ok and the current D implementation is broken. I have an example in one of my previous posts.

Thanks. So, does Java have something like "friend" in C++? Does a class ever gain access to another classes 'private' data? If so, how? If not, why has it never been required? (as it was in C++? debatable?) Regan
Nov 09 2005
parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 So, does Java have something like "friend" in C++? Does a class ever 
 gain  access to another classes 'private' data? If so, how? If not, why 
 has it  never been required? (as it was in C++? debatable?)

Yes, all classes in the same package (Java package = D module) share their private data. This is no problem (unless you run out of inodes ;)) since all non-friendly classes can be split into separate packages.
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 02:34:36 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 So, does Java have something like "friend" in C++? Does a class ever  
 gain  access to another classes 'private' data? If so, how? If not, why  
 has it  never been required? (as it was in C++? debatable?)

Yes, all classes in the same package (Java package = D module) share their private data. This is no problem (unless you run out of inodes ;)) since all non-friendly classes can be split into separate packages.

Ahh, so that works like it does in D... only D calls them modules to Java's packages and D have another thing called a "package" and a protection attribute for that too. Thanks. Regan
Nov 09 2005
parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 On Thu, 10 Nov 2005 02:34:36 +0200, Jari-Matti Mäkelä  
 <jmjmak invalid_utu.fi> wrote:
 
 Regan Heath wrote:

 So, does Java have something like "friend" in C++? Does a class ever  
 gain  access to another classes 'private' data? If so, how? If not, 
 why  has it  never been required? (as it was in C++? debatable?)

Yes, all classes in the same package (Java package = D module) share their private data. This is no problem (unless you run out of inodes ;)) since all non-friendly classes can be split into separate packages.

Ahh, so that works like it does in D... only D calls them modules to Java's packages and D have another thing called a "package" and a protection attribute for that too.

similarities with the modules in D, Java packages are physically (file system) like D packages. Actually Java packages may consist of multiple source files. Confusing, eh?
Nov 09 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 02:56:49 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 On Thu, 10 Nov 2005 02:34:36 +0200, Jari-Matti Mäkelä   
 <jmjmak invalid_utu.fi> wrote:

 Regan Heath wrote:

 So, does Java have something like "friend" in C++? Does a class ever   
 gain  access to another classes 'private' data? If so, how? If not,  
 why  has it  never been required? (as it was in C++? debatable?)

Yes, all classes in the same package (Java package = D module) share their private data. This is no problem (unless you run out of inodes ;)) since all non-friendly classes can be split into separate packages.

Java's packages and D have another thing called a "package" and a protection attribute for that too.

similarities with the modules in D, Java packages are physically (file system) like D packages. Actually Java packages may consist of multiple source files. Confusing, eh?

D has "packages" too, and they too consist of multiple files. So, "package" in D is the same as "package" in Java, but, access to private members is restricted in D to modules as opposed to packages in Java. Is that a good summary? Regan
Nov 09 2005
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Jari-Matti Mäkelä wrote:
 Regan Heath wrote:

 So, does Java have something like "friend" in C++? Does a class ever
 gain  access to another classes 'private' data? If so, how? If not,
 why has it  never been required? (as it was in C++? debatable?)

Yes, all classes in the same package (Java package = D module) share their private data. This is no problem (unless you run out of inodes ;)) since all non-friendly classes can be split into separate packages.

which there is allways exactly one in each source file. Furthermore, "all classes in the same package" do not share private data. 'private' restricts acess to the class-scope only. Jari-Matti Mäkelä wrote:
 Regan Heath wrote:
 
 Java does have a similar system using packages. You can declare a 
 top-level class as public/package (no keyword). 

 Only one public class
 per package (module) is allowed, other classes must be "hidden" so that 
 they're not polluting the namespace when the package is imported. 

and in a Java module too (the public top-level class and public inner classes for example)
 Therefore only public classes are accessible from other modules. You 
 need to explicitely write the "package foobar" line inside the source to 
 use packages.
 

package) you use the 'import' statement. The 'package' statement in Java defines which package the module is part of (analagous to D's 'module' statement) -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Nov 11 2005
parent =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Bruno Medeiros wrote:
 Jari-Matti Mäkelä wrote:
  > Regan Heath wrote:
  >
  >> So, does Java have something like "friend" in C++? Does a class ever
  >> gain  access to another classes 'private' data? If so, how? If not,
  >> why has it  never been required? (as it was in C++? debatable?)
  >
  >
  > Yes, all classes in the same package (Java package = D module) share
  > their private data. This is no problem (unless you run out of inodes ;))
  > since all non-friendly classes can be split into separate packages.
 No. Modules in Java are the top-level classes in each source file, of 
 which there is allways exactly one in each source file.  Furthermore, 
 "all classes in the same package" do not share private data. 'private' 
 restricts acess to the class-scope only.

Sorry, I meant that all classes in the same file share their private data. I know the private inner classes are an exception to this, but tried to keep things simple.
 
 
 Jari-Matti Mäkelä wrote:
 
 Regan Heath wrote:

 Java does have a similar system using packages. You can declare a 
 top-level class as public/package (no keyword). 

> Only one public class
 per package (module) is allowed, other classes must be "hidden" so 
 that they're not polluting the namespace when the package is imported. 

No, there can be several public classes in a Java package (obviously) and in a Java module too (the public top-level class and public inner classes for example)

Oh my, I though I was writing about files but somehow typed that darn package there again. Again, inner classes are an exception, but I wanted to stay in top-level classes since we had different opinions on that particular level. That's it, gotta stop posting in the middle of the night :/
 
 Therefore only public classes are accessible from other modules. You 
 need to explicitely write the "package foobar" line inside the source 
 to use packages.

package) you use the 'import' statement. The 'package' statement in Java defines which package the module is part of (analagous to D's 'module' statement)

Yes, you're right. I'm not that sure what I actually meant but I think it had something to do with implicit compiler logic. At least Sun javac requires you to explicitely define the name of the package in the source file. Otherwise it complains "file does not contain class foo.bar". D does not require you to do this, right? The other thing is that unless you explicitely define the package, javac treats all those files in that directory as if they were in the same module. At least that's how I see it since you're able to access all private members of other top-level classes then. What I said about public classes is completely true. If the .java-file is called a module, you really can't access the non-public classes from other modules. (Actually you can access non-static inner classes using their public superclass/interface, but that's another story.)
Nov 11 2005
prev sibling parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
(sorry, had to answer twice - this message was a bit confusing :)

Regan Heath wrote:
 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.


don't need these "local"-members anywhere. The idea behind "friends" and D modules is not that you'll put all your classes in the same module. If the classes are somehow internally related, you can have them in the same module, otherwise keep them in separate modules. That way there's no need the make things more complex than they really are.
 A further useful protection facility would be to make a class definition
 invisible to other source files. Currently the use of "private" on the
 "class" definition is ignored but it could be used to hide a class from
 other modules. The current technique of designating the class constructor
 as private is a bit obtuse and smacks of a "workaround fix" rather than a
 thought out solution to the real problem.

That's cos it was a workaround ;)

No, that's not a workaround. The private constructor exists because that way you can't instantiate a class outside the class body. It has nothing to do with visibility keywords on the module level.
 It would be nice to be able to hide a class with a single keyword in 
 the  logical place. It seems that place is on the class definition, I 
 agree.

From http://www.digitalmars.com/d/attribute.html: "Static does not have the additional C meaning of being local to a file. Use the private attribute in D to achieve that. For example: module foo; int x = 3; // x is global private int y = 4; // y is local to module foo Now the D specification has the functionality you need, but the implementation doesn't care about private-keyword. I hope that's the bug we are all hunting down here, right?
Nov 09 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 10 Nov 2005 01:49:14 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 (sorry, had to answer twice - this message was a bit confusing :)

 Regan Heath wrote:
 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward>  
 wrote:

 I think I'd prefer a new protection attribute to limit scope to within  
 a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.


don't need these "local"-members anywhere. The idea behind "friends" and D modules is not that you'll put all your classes in the same module. If the classes are somehow internally related, you can have them in the same module, otherwise keep them in separate modules. That way there's no need the make things more complex than they really are.

I agree.
 A further useful protection facility would be to make a class  
 definition
 invisible to other source files. Currently the use of "private" on the
 "class" definition is ignored but it could be used to hide a class from
 other modules. The current technique of designating the class  
 constructor
 as private is a bit obtuse and smacks of a "workaround fix" rather  
 than a
 thought out solution to the real problem.


No, that's not a workaround. The private constructor exists because that way you can't instantiate a class outside the class body. It has nothing to do with visibility keywords on the module level.

My mistake, I agree.
 It would be nice to be able to hide a class with a single keyword in  
 the  logical place. It seems that place is on the class definition, I  
 agree.

From http://www.digitalmars.com/d/attribute.html: "Static does not have the additional C meaning of being local to a file. Use the private attribute in D to achieve that. For example: module foo; int x = 3; // x is global private int y = 4; // y is local to module foo Now the D specification has the functionality you need, but the implementation doesn't care about private-keyword. I hope that's the bug we are all hunting down here, right?

I beliece that currently the 'private' keyword is only applied to instances of things i.e. an int or a class reference. It's not being applied to declarations i.e. enum, class, struct, alias, typdef etc. So, does the spec say it should? (is it a bug?) Do we think it should? (is it a new feature to be added?) Regan
Nov 09 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dku1m7$2n32$1 digitaldaemon.com>,
=?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= says...
(sorry, had to answer twice - this message was a bit confusing :)

Regan Heath wrote:
 On Wed, 9 Nov 2005 16:41:55 +1100, Derek Parnell <derek psych.ward> wrote:
 
 I think I'd prefer a new protection attribute to limit scope to within a
 class or struct. Something like ...

  class Aux
  {
  local:
  static int invisible_outside_class = 8;
  private:
  static int n = 5;
  static float f = 3.14;
  }

 And even rename "private" to "module" to make it more clear as to its
 scope.


don't need these "local"-members anywhere. The idea behind "friends" and D modules is not that you'll put all your classes in the same module. If the classes are somehow internally related, you can have them in the same module, otherwise keep them in separate modules. That way there's no need the make things more complex than they really are.

I dont understand? How do you achieve "friend" behavior between two classes in different modules?
 A further useful protection facility would be to make a class definition
 invisible to other source files. Currently the use of "private" on the
 "class" definition is ignored but it could be used to hide a class from
 other modules. The current technique of designating the class constructor
 as private is a bit obtuse and smacks of a "workaround fix" rather than a
 thought out solution to the real problem.

That's cos it was a workaround ;)

No, that's not a workaround. The private constructor exists because that way you can't instantiate a class outside the class body. It has nothing to do with visibility keywords on the module level.
 It would be nice to be able to hide a class with a single keyword in 
 the  logical place. It seems that place is on the class definition, I 
 agree.

From http://www.digitalmars.com/d/attribute.html: "Static does not have the additional C meaning of being local to a file. Use the private attribute in D to achieve that. For example: module foo; int x = 3; // x is global private int y = 4; // y is local to module foo Now the D specification has the functionality you need, but the implementation doesn't care about private-keyword. I hope that's the bug we are all hunting down here, right?

Nov 09 2005
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Tomás Rossi wrote:
I disagree. Private is a standard keyword in many oo-languages. You 
don't need these "local"-members anywhere. The idea behind "friends" and 
D modules is not that you'll put all your classes in the same module. If 
the classes are somehow internally related, you can have them in the 
same module, otherwise keep them in separate modules. That way there's 
no need the make things more complex than they really are.

I dont understand? How do you achieve "friend" behavior between two classes in different modules?

both "local"- and "friend"-functionality at the same time. Friend-relationship means that the private members are accessible, this local-visibility seems the mean that the private members are inaccessible inside the "friend" class.
Nov 09 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dku4mo$2p0o$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
Tomás Rossi wrote:
I disagree. Private is a standard keyword in many oo-languages. You 
don't need these "local"-members anywhere.



Uh? Why are you so sure?
The idea behind "friends" and 
D modules is not that you'll put all your classes in the same module.



UUHhh?! I thought that "friends" concept of D was to put all the "friend" classes in the same module. I don't know how to do it if not.
If the classes are somehow internally related, you can have them in the 
same module, otherwise keep them in separate modules. That way there's 
no need the make things more complex than they really are.

different modules?

both "local"- and "friend"-functionality at the same time.

I know and I didn't mean that.
Friend-relationship means that the private members are accessible, this 
local-visibility seems the mean that the private members are 
inaccessible inside the "friend" class.

Local means: THAT MEMBER (the local one), can´t be accessed by another class in the same module. Regards Hope you catched my train of thought this time :) Tom
Nov 09 2005
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Tomás Rossi wrote:
If the classes are somehow internally related, you can have them in the 
same module, otherwise keep them in separate modules. That way there's 
no need the make things more complex than they really are.

I dont understand? How do you achieve "friend" behavior between two classes in different modules?

Actually I think I'm not following your train of thought. You can't have both "local"- and "friend"-functionality at the same time.

I know and I didn't mean that.

So what's the problem then? If you want classes to be friends, put them in the _same_ module, otherwise put them in _separate_ modules. Think of the friend classes as an extra. You can do everything you want without any friend classes. Now if you find classes that share their private members a lot, you may want to reduce the amount of pointless wrappers around private properties. Ok, now you can use private classes. So, that's it. If you just need the basic inheritance or customer relationship, there's no need to put these classes/functions in the same module, right?
Friend-relationship means that the private members are accessible, this 
local-visibility seems the mean that the private members are 
inaccessible inside the "friend" class.

Local means: THAT MEMBER (the local one), can´t be accessed by another class in the same module.

Therefore the local keyword means that no other class in any module can access that member either. But this visibility is already possible to achieve using separate modules. The only "shortcoming" with modules is that you cannot have both local and private members in the same class. But I find that requirement insane since the "friend"-behaviour isn't the default access method in oo-languages - you can use encapsulation.
 Hope you catched my train of thought this time :)

I hope that too :)
Nov 10 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkv77l$12b6$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
Tomás Rossi wrote:
If the classes are somehow internally related, you can have them in the 
same module, otherwise keep them in separate modules. That way there's 
no need the make things more complex than they really are.

I dont understand? How do you achieve "friend" behavior between two classes in different modules?

Actually I think I'm not following your train of thought. You can't have both "local"- and "friend"-functionality at the same time.

I know and I didn't mean that.

So what's the problem then? If you want classes to be friends, put them in the _same_ module, otherwise put them in _separate_ modules. Think of the friend classes as an extra. You can do everything you want without any friend classes. Now if you find classes that share their private members a lot, you may want to reduce the amount of pointless wrappers around private properties. Ok, now you can use private classes. So, that's it. If you just need the basic inheritance or customer relationship, there's no need to put these classes/functions in the same module, right?
Friend-relationship means that the private members are accessible, this 
local-visibility seems the mean that the private members are 
inaccessible inside the "friend" class.

Local means: THAT MEMBER (the local one), can´t be accessed by another class in the same module.

Therefore the local keyword means that no other class in any module can access that member either. But this visibility is already possible to achieve using separate modules. The only "shortcoming" with modules is that you cannot have both local and private members in the same class. But I find that requirement insane since the "friend"-behaviour isn't the default access method in oo-languages - you can use encapsulation.

I know that from an OO point of view friendship is ugly, but as Walter said, sometimes you have to break the rules. :) As an example of what C++ friendship could do vs. D inside-the-same-module approach, I mentioned C++ iostream "<< operator" overload kind of friendship. This is by far impossible with D approach. Take a look of the previous discussion with Regan for more details. Hope I had explained myself.
 Hope you catched my train of thought this time :)

I hope that too :)

Tom
Nov 10 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 9 Nov 2005 05:12:23 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszygscna23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system.

What about having another attribute to allow other entities in the same module to gain access to that members? For example:

<snip example> You could. But why benfit does that have over the current way? Chances are you're the author of all the code in the module, if so what's the point of restricting that code from interacting with itself to any extent it needs/wants to? My perspective is that if you look at the D module as being comparable to a class from C++/Java (in terms of being the encapsulating entity) then take your suggestion back to C++/Java it's like saying, why not have an attribute to allow part of my class access to the another part of my class. Now, you may or may not believe that's a valid comparrison, I reckon it depends on how you view D's modules, are they just files that contain code, or are they an encapsulating entity? Regan
Nov 08 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 09 Nov 2005 18:42:24 +1300, Regan Heath wrote:


 You could. But why benfit does that have over the current way?
 
 Chances are you're the author of all the code in the module, if so what's  
 the point of restricting that code from interacting with itself to any  
 extent it needs/wants to?
 
 My perspective is that if you look at the D module as being comparable to  
 a class from C++/Java (in terms of being the encapsulating entity) then  
 take your suggestion back to C++/Java it's like saying, why not have an  
 attribute to allow part of my class access to the another part of my class.

The only thing I can see as a benefit is that it reduces cohesion between classes and makes them more independent. I enhances the separation of concerns within the module. It is a similar situation with the use of goto. Even though uses of goto are probably written by the same author in the same file, their presence reduces the independence of the code sections. With 'friend' members, coders, and in particular maintenance coders, need to be aware that changes to such members have the potential of creating side effects that are not in the lexical vicinity of the member. In other words, currently if I change a "private" member's data type I should also scan the other classes in the module, and module level code, to see if my change upsets them. If that member was designated as locally scoped to the enclosing class, my change has less code to upset.
 Now, you may or may not believe that's a valid comparrison, I reckon it  
 depends on how you view D's modules, are they just files that contain  
 code, or are they an encapsulating entity?

I think that the module concept as an encapsulating entity is a neat idea too. -- Derek (skype: derek.j.parnell) Melbourne, Australia 9/11/2005 4:47:51 PM
Nov 08 2005
parent reply Georg Wrede <georg.wrede nospam.org> writes:
Derek Parnell wrote:

 In other words, currently if I change a "private" member's data type
 I should also scan the other classes in the module, and module level 
 code, to see if my change upsets them.

That is unacceptable!
 I think that the module concept as an encapsulating entity is a neat 
 idea too.

True. But exposing parts of a class to the "outside", should always have to be explicit! What was it that Walter once wrote? Someting like: In D, doing the right thing should be natural, but as a pragmatic language D doesn't restrict the programmer unduely. Or something like it anyway. --- If we had class, module, and descendant visibility in an unsurprising way, then D would be much easier to learn. And there'd be less errors.
Nov 11 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 11 Nov 2005 21:16:52 +0200, Georg Wrede wrote:

 Derek Parnell wrote:
 
 In other words, currently if I change a "private" member's data type
 I should also scan the other classes in the module, and module level 
 code, to see if my change upsets them.

That is unacceptable!

Yes it is.
 I think that the module concept as an encapsulating entity is a neat 
 idea too.

True. But exposing parts of a class to the "outside", should always have to be explicit!

Very true. Its similar to the default "public" import issue.
 What was it that Walter once wrote? Someting like: In D, doing the right 
 thing should be natural, but as a pragmatic language D doesn't restrict 
 the programmer unduely. Or something like it anyway.
 
 ---
 
 If we had class, module, and descendant visibility in an unsurprising 
 way, then D would be much easier to learn. And there'd be less errors.

Amen, brother! Couldn't agree more. -- Derek Parnell Melbourne, Australia 12/11/2005 7:25:56 AM
Nov 11 2005
next sibling parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dbke8a2orfcb.msjstcpt7tb5.dlg 40tude.net>, Derek Parnell says...
On Fri, 11 Nov 2005 21:16:52 +0200, Georg Wrede wrote:

 Derek Parnell wrote:
 
 In other words, currently if I change a "private" member's data type
 I should also scan the other classes in the module, and module level 
 code, to see if my change upsets them.

That is unacceptable!

Yes it is.

We are three.
 I think that the module concept as an encapsulating entity is a neat 
 idea too.

True. But exposing parts of a class to the "outside", should always have to be explicit!

Very true. Its similar to the default "public" import issue.

We should establish a political party, having the same ideals :P
 What was it that Walter once wrote? Someting like: In D, doing the right 
 thing should be natural, but as a pragmatic language D doesn't restrict 
 the programmer unduely. Or something like it anyway.
 
 ---
 
 If we had class, module, and descendant visibility in an unsurprising 
 way, then D would be much easier to learn. And there'd be less errors.

Amen, brother! Couldn't agree more.

At last! I was feeling a little lonely here defending my point. I was unfairly called a C++ programmer trying to desing in C++ and write in D (:-D maybe there is a little true in that but that's because C++ respect class independency)... but I'm sure D shouldn´t commit such a crime against class independency (at least not by default). For many time classes were total independent encapsulating objects and it were nice, we all liked it that way. Taking their nice encapsulation capabilities isn't a good idea. Regards and dont let me fight alone again for so many time! :P Tom
Nov 11 2005
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Derek Parnell wrote:
 On Fri, 11 Nov 2005 21:16:52 +0200, Georg Wrede wrote:
 
 
Derek Parnell wrote:


In other words, currently if I change a "private" member's data type
I should also scan the other classes in the module, and module level 
code, to see if my change upsets them.

That is unacceptable!

Yes it is.

I agree. However, if there should be a protection attribute that restricts access to the enclosing scope only (and I suppose we are also agreeing that there should be one), then that should be "private" and not something else, like "local". -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Nov 12 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dl50tq$2uss$1 digitaldaemon.com>, Bruno Medeiros says...
Derek Parnell wrote:
 On Fri, 11 Nov 2005 21:16:52 +0200, Georg Wrede wrote:
 
 
Derek Parnell wrote:


In other words, currently if I change a "private" member's data type
I should also scan the other classes in the module, and module level 
code, to see if my change upsets them.

That is unacceptable!

Yes it is.

I agree. However, if there should be a protection attribute that restricts access to the enclosing scope only (and I suppose we are also agreeing that there should be one), then that should be "private" and not something else, like "local".

Before enthusiastically proposing keywords, the majority should agree in that something has to be done to accomplish this enhancement. Besides, it is clear (as Regan posted it before) that one single keyword isn't enough. Must be three of them (I think) or a modifier for either of the three existing attributes (pitifully modifiers are ugly and introduces some complexity to the language -I believe-). Something it's clear, this must be a serious proposal so Walter can take it into account. Tom
Nov 12 2005
prev sibling parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszyksyap23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 05:12:23 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 In article <opszygscna23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Wed, 9 Nov 2005 03:43:17 +0000 (UTC), Tomás Rossi
 <Tomás_member pathlink.com> wrote:
 ====>test.d:

 class m { private static int a = 5; }

 void main() {
   printf("%d",m.a);
 }

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

Think of it as a replacement for the "friend" system in C++. "friend" in C++ is an example of a solution to the need to obtain access to a part of a class that is normally off limits to external methods. Technically (I believe) it's a violation of strict OO principles. Does Java have a similar mechanism? Does the need never arise in Java? In order to get into the way D does it you have to adjust your perspective such that the "module" is the encapsulating entity, as opposed to the class. A module in D encapsulates an idea/concept/tool and exposes an interface which other modules can then import and use. It can expose several classes, classes which can be tightly bound together if that is what is required. I prefer it to the C++ "friend" system.

What about having another attribute to allow other entities in the same module to gain access to that members? For example:

<snip example> You could. But why benfit does that have over the current way? Chances are you're the author of all the code in the module, if so what's the point of restricting that code from interacting with itself to any extent it needs/wants to? My perspective is that if you look at the D module as being comparable to a class from C++/Java (in terms of being the encapsulating entity) then take your suggestion back to C++/Java it's like saying, why not have an attribute to allow part of my class access to the another part of my class.

With that perspective, you could make all the members of your C++ classes public and trust that you would never break the invariant of your class (at least as long as you are the only user of your objects). I've founded myself trying to break the rules many times without noting it. For example, when i have to make changes to some old code, i would like not to worry about breaking auxiliar objects coherency. Besides, not having the chance to have real PRIVATE members between classes inside the same module is SO NOT-ELEGANT.
Now, you may or may not believe that's a valid comparrison, I reckon it  
depends on how you view D's modules, are they just files that contain  
code, or are they an encapsulating entity?

Regan

Tom
Nov 09 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 9 Nov 2005 13:48:08 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 Chances are you're the author of all the code in the module, if so  
 what's
 the point of restricting that code from interacting with itself to any
 extent it needs/wants to?

 My perspective is that if you look at the D module as being comparable  
 to
 a class from C++/Java (in terms of being the encapsulating entity) then
 take your suggestion back to C++/Java it's like saying, why not have an
 attribute to allow part of my class access to the another part of my  
 class.

With that perspective, you could make all the members of your C++ classes public and trust that you would never break the invariant of your class (at least as long as you are the only user of your objects).

No true, as I still have/want encapsulation with D, it's just at the module level instead of the class level. My objects in D have encapsulation when I require it, they're in different modules.
 I've founded myself trying to break the rules many times without noting  
 it.

It is true that the compiler will not stop you breaking, thus not help you enforce encapsulation between classes in the same module.
 For example, when i have to make
 changes to some old code, i would like not to worry about breaking  
 auxiliar objects coherency. Besides, not having the chance to have real  
 PRIVATE members between classes inside the same module is SO NOT-ELEGANT.

If you require encapsulation between objects place them in different modules. You have to design in D, not design in C++, write in D and expect it to work the same. Regan
Nov 09 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <opszzqptfx23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Wed, 9 Nov 2005 13:48:08 +0000 (UTC), Tomás Rossi  
<Tomás_member pathlink.com> wrote:
 Chances are you're the author of all the code in the module, if so  
 what's
 the point of restricting that code from interacting with itself to any
 extent it needs/wants to?

 My perspective is that if you look at the D module as being comparable  
 to
 a class from C++/Java (in terms of being the encapsulating entity) then
 take your suggestion back to C++/Java it's like saying, why not have an
 attribute to allow part of my class access to the another part of my  
 class.

With that perspective, you could make all the members of your C++ classes public and trust that you would never break the invariant of your class (at least as long as you are the only user of your objects).

No true, as I still have/want encapsulation with D, it's just at the module level instead of the class level. My objects in D have encapsulation when I require it, they're in different modules.

It's still a little shocking to me and hard to accept the fact that D took away the class encapsulation capabilities and transfer them to the module. I know it'd be a lot more neat to make an attribute that limits a class to interfere with another class in the same module. I know that some day i'll find an example where i'll show that this requirement is needed :)
 I've founded myself trying to break the rules many times without noting  
 it.

It is true that the compiler will not stop you breaking, thus not help you enforce encapsulation between classes in the same module.
 For example, when i have to make
 changes to some old code, i would like not to worry about breaking  
 auxiliar objects coherency. Besides, not having the chance to have real  
 PRIVATE members between classes inside the same module is SO NOT-ELEGANT.

If you require encapsulation between objects place them in different modules. You have to design in D, not design in C++, write in D and expect it to work the same.

I'm not doing that. Tom
Nov 09 2005
parent Georg Wrede <georg.wrede nospam.org> writes:
Tomás Rossi wrote:
 It's still a little shocking to me and hard to accept the fact that D
 took away the class encapsulation capabilities and transfer them to
 the module. I know it'd be a lot more neat to make an attribute that
 limits a class to interfere with another class in the same module. I
 know that some day i'll find an example where i'll show that this
 requirement is needed :)

I definitely think we should have both. In some projects I can see modules used as a way of grouping many related small classes. I should be able to choose which methods and attributes I want private, visible to the module, or the world. I can see no benefit in only having either class or module visibility, without the other. It's like saying we can have a language either with integers or with reals, but not both. --- Hell, these requirements change even during the lifetime of a program, from early versions to later and larger versions. In large scale software development, one does not want to put every single little class in its own file just to be sure you can enforce encapsulation. On the other hand, friendliness between classes is a must in certain situations (especially with a Pragmatic Language), and in those situations it would be very useful to implement it with module encapsulation. --- So, choise in granularity, please.
Nov 11 2005
prev sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Tomás Rossi wrote:
Here is a yet another simple test case:

====>test.cpp:

#include <stdio.h>

class m { private: static const int a = 5; };

int main() {
  printf("%d", m::a);
  return 0;
}

====>test.java:

class m { private static int a = 5; }

public class m2 {
  public static void main(String[] p) {
    System.out.println(m.a);
  }
}

====>test.d:

class m { private static int a = 5; }

void main() {
  printf("%d",m.a);
}

Ok, Regan showed me earlier that this (private member of a class in the same module) is accessible from anyplace in the enclosing module, so it's not a bug. (http://www.digitalmars.com/d/attribute.html) I personally think that this behavior is useless and confusing.

I like the idea that all declarations are "friends" in the same module. But now _all_ top level symbols can be imported to another module. I think this an error in language design since now it's possible that all classes in separate modules become friends when "public" import is used. This has a nasty side effect: module module1: class foo { int a; } module module2: import module1; module module3: import module1; module module4: import module2, module3; foo a = new foo(); // now should we use module2.foo or module3.foo I know this probably doesn't produce an error right now. But with bigger projects it becomes a nuisance. As a practical workaround you need to import module2 in module3 to prevent some nasty ambiguities. I'm still working on a minimal test case. What I was saying was that D desperately needs a way to make code invisible in a separate module. You see this also works: ====>module1.d: module module1; private class foo { private static int a = 5; } ====>module2.d: module module2; private import module1; void main() { printf("%d", foo.a); --- As a workaround I need to chain these modules with multiple private imports now: module module1; private class foo { private static int a = 5; } module workaround: private import module1; module module3; import workaround; void main() {printf("%d", foo.a);} //now it works(ie. doesn't compile)
Nov 09 2005
prev sibling parent reply "Garett Bass" <garettbass studiotekne.com> writes:
 Garret, do you want to post to bugs, or should I?

 - Dave

Dave, I posted this issue to digitalmars.D.bugs last night. Regards, Garett
Nov 08 2005
parent reply Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkr5fu$msq$1 digitaldaemon.com>, Garett Bass says...
 Garret, do you want to post to bugs, or should I?

 - Dave

Dave, I posted this issue to digitalmars.D.bugs last night. Regards, Garett

Why cant i see the post? The last bug that appears is Oct 03 2005 Ddoc BODY macro A little out of date... The URL is http://www.digitalmars.com/d/archives/digitalmars/D/bugs/ Am i right? Tom
Nov 08 2005
parent Tomás Rossi <Tomás_member pathlink.com> writes:
In article <dkrdcq$19tq$1 digitaldaemon.com>, Tomás Rossi says...
In article <dkr5fu$msq$1 digitaldaemon.com>, Garett Bass says...
 Garret, do you want to post to bugs, or should I?

 - Dave

Dave, I posted this issue to digitalmars.D.bugs last night. Regards, Garett

Why cant i see the post? The last bug that appears is Oct 03 2005 Ddoc BODY macro A little out of date... The URL is http://www.digitalmars.com/d/archives/digitalmars/D/bugs/ Am i right?

Oh, i guess this was the one http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs Sorry, it was a lapsus! (i'm a little new here) Tom
Nov 08 2005