November 09, 2005
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
November 09, 2005
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
November 09, 2005
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
November 09, 2005
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
November 09, 2005
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
November 09, 2005
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
November 09, 2005
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
November 09, 2005
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.
November 09, 2005
(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.
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.

>> 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?
November 10, 2005
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